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 |                                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) | Daniel (11 September 2001) | ||||||
| - Added verbose output for SSL connections that output the server | - Added verbose output for SSL connections that output the server | ||||||
|   certificate's start and expire dates. As suggested by Paul Harrington. |   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 | 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, | 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 | 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 | in all copies of the Software. | ||||||
| this permission notice appear in supporting documentation. |  | ||||||
|  |  | ||||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|   | |||||||
| @@ -67,3 +67,9 @@ pkgadd: | |||||||
| 	make install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \ | 	make install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \ | ||||||
| 	cat LEGAL MITX.txt MPL-1.1.txt > $(srcdir)/packages/Solaris/copyright ; \ | 	cat LEGAL MITX.txt MPL-1.1.txt > $(srcdir)/packages/Solaris/copyright ; \ | ||||||
| 	cd $(srcdir)/packages/Solaris && $(MAKE) package | 	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: |   The official download mirror sites are: | ||||||
|  |  | ||||||
|         Sweden    -- ftp://ftp.sunet.se/pub/www/utilities/curl/ |         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/ |         Germany   -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/ | ||||||
|  |  | ||||||
|   To download the very latest source off the CVS server do this: |   To download the very latest source off the CVS server do this: | ||||||
|   | |||||||
| @@ -54,3 +54,11 @@ | |||||||
|  |  | ||||||
| /* Define if you have a working OpenSSL installation */ | /* Define if you have a working OpenSSL installation */ | ||||||
| #undef OPENSSL_ENABLED | #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 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 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 | 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_DEFINE(NEED_REENTRANT) | ||||||
| 	AC_MSG_RESULT(yes)], | 	AC_MSG_RESULT(yes)], | ||||||
| 	AC_MSG_RESULT(no))])]) | 	AC_MSG_RESULT(no))])]) | ||||||
|  |  | ||||||
| ]) | ]) | ||||||
|  |  | ||||||
| AC_DEFUN(CURL_CHECK_GETHOSTBYADDR_R, | AC_DEFUN(CURL_CHECK_GETHOSTBYADDR_R, | ||||||
| @@ -220,8 +323,6 @@ rc = gethostbyaddr_r(address, length, type, &h, | |||||||
| 	    ac_cv_gethostbyaddr_args=8],[ | 	    ac_cv_gethostbyaddr_args=8],[ | ||||||
| 	    AC_MSG_RESULT(no) | 	    AC_MSG_RESULT(no) | ||||||
| 	    have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r"])])])])]) | 	    have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r"])])])])]) | ||||||
|  |  | ||||||
|  |  | ||||||
| ]) | ]) | ||||||
|  |  | ||||||
| AC_DEFUN(CURL_CHECK_GETHOSTBYNAME_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 check for number of arguments to gethostbyname_r. it might take | ||||||
|   dnl either 3, 5, or 6 arguments. |   dnl either 3, 5, or 6 arguments. | ||||||
|   AC_CHECK_FUNCS(gethostbyname_r,[ |   AC_CHECK_FUNCS(gethostbyname_r,[ | ||||||
|     AC_MSG_CHECKING(if gethostbyname_r takes 3 arguments) |     AC_MSG_CHECKING([if gethostbyname_r takes 3 arguments]) | ||||||
|     AC_TRY_RUN([ |     AC_TRY_COMPILE([ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
|  |  | ||||||
| int | int | ||||||
| main () { | gethostbyname_r(const char *, struct hostent *, struct hostent_data *);],[ | ||||||
| struct hostent h; | gethostbyname_r(NULL, NULL, NULL);],[ | ||||||
| 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); }],[ |  | ||||||
|       AC_MSG_RESULT(yes) |       AC_MSG_RESULT(yes) | ||||||
|       AC_DEFINE(HAVE_GETHOSTBYNAME_R_3) |       AC_DEFINE(HAVE_GETHOSTBYNAME_R_3) | ||||||
|       ac_cv_gethostbyname_args=3],[ |       ac_cv_gethostbyname_args=3],[ | ||||||
|       AC_MSG_RESULT(no) |       AC_MSG_RESULT(no) | ||||||
|       AC_MSG_CHECKING(if gethostbyname_r with -D_REENTRANT takes 3 arguments) |       AC_MSG_CHECKING([if gethostbyname_r with -D_REENTRANT takes 3 arguments]) | ||||||
|       AC_TRY_RUN([ |       AC_TRY_COMPILE([ | ||||||
| #define _REENTRANT | #define _REENTRANT | ||||||
|  |  | ||||||
| #include <string.h> | #include <string.h> | ||||||
| @@ -258,53 +352,34 @@ exit (rc != 0 ? 1 : 0); }],[ | |||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
|  |  | ||||||
| int | int | ||||||
| main () { | gethostbyname_r(const char *,struct hostent *, struct hostent_data *);],[ | ||||||
| struct hostent h; | gethostbyname_r(NULL, NULL, NULL);],[ | ||||||
| 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); }],[ |  | ||||||
| 	AC_MSG_RESULT(yes) | 	AC_MSG_RESULT(yes) | ||||||
| 	AC_DEFINE(HAVE_GETHOSTBYNAME_R_3) | 	AC_DEFINE(HAVE_GETHOSTBYNAME_R_3) | ||||||
| 	AC_DEFINE(NEED_REENTRANT) | 	AC_DEFINE(NEED_REENTRANT) | ||||||
| 	ac_cv_gethostbyname_args=3],[ | 	ac_cv_gethostbyname_args=3],[ | ||||||
| 	AC_MSG_RESULT(no) | 	AC_MSG_RESULT(no) | ||||||
| 	AC_MSG_CHECKING(if gethostbyname_r takes 5 arguments) | 	AC_MSG_CHECKING([if gethostbyname_r takes 5 arguments]) | ||||||
| 	AC_TRY_RUN([ | 	AC_TRY_COMPILE([ | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
|  |  | ||||||
| int | struct hostent * | ||||||
| main () { | gethostbyname_r(const char *, struct hostent *, char *, int, int *);],[ | ||||||
| struct hostent *hp; | gethostbyname_r(NULL, NULL, NULL, 0, NULL);],[ | ||||||
| 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); }],[ |  | ||||||
| 	  AC_MSG_RESULT(yes) | 	  AC_MSG_RESULT(yes) | ||||||
| 	  AC_DEFINE(HAVE_GETHOSTBYNAME_R_5) | 	  AC_DEFINE(HAVE_GETHOSTBYNAME_R_5) | ||||||
|           ac_cv_gethostbyname_args=5],[ |           ac_cv_gethostbyname_args=5],[ | ||||||
| 	  AC_MSG_RESULT(no) | 	  AC_MSG_RESULT(no) | ||||||
| 	  AC_MSG_CHECKING(if gethostbyname_r takes 6 arguments) | 	  AC_MSG_CHECKING([if gethostbyname_r takes 6 arguments]) | ||||||
| 	  AC_TRY_RUN([ | 	  AC_TRY_COMPILE([ | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
|  |  | ||||||
| int | int | ||||||
| main () { | gethostbyname_r(const char *, struct hostent *, char *, size_t, | ||||||
| struct hostent h; | struct hostent **, int *);],[ | ||||||
| struct hostent *hp; | gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL);],[ | ||||||
| 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); }],[ |  | ||||||
| 	    AC_MSG_RESULT(yes) | 	    AC_MSG_RESULT(yes) | ||||||
| 	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_6) | 	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_6) | ||||||
|             ac_cv_gethostbyname_args=6],[ |             ac_cv_gethostbyname_args=6],[ | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								build_vms.com
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								build_vms.com
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -5,9 +5,7 @@ die(){ | |||||||
| 	exit | 	exit | ||||||
| } | } | ||||||
|  |  | ||||||
| MAKEFILES=`find . -name Makefile.am | sed 's/\.am$//'` | automake          || die "The command 'automake $MAKEFILES' failed" | ||||||
|  |  | ||||||
| automake $MAKEFILES || die "The command 'automake $MAKEFILES' failed" |  | ||||||
| aclocal           || die "The command 'aclocal' failed" | aclocal           || die "The command 'aclocal' failed" | ||||||
| autoheader        || die "The command 'autoheader' failed" | autoheader        || die "The command 'autoheader' failed" | ||||||
| autoconf          || die "The command 'autoconf' failed" | autoconf          || die "The command 'autoconf' failed" | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | |||||||
| #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 | #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 | ||||||
| #   Free Software Foundation, Inc. | #   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 | # 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 | # under the terms of the GNU General Public License as published by | ||||||
| @@ -393,6 +393,7 @@ EOF | |||||||
| 	echo clipper-intergraph-clix${UNAME_RELEASE} | 	echo clipper-intergraph-clix${UNAME_RELEASE} | ||||||
| 	exit 0 ;; | 	exit 0 ;; | ||||||
|     mips:*:*:UMIPS | mips:*:*:RISCos) |     mips:*:*:UMIPS | mips:*:*:RISCos) | ||||||
|  | 	eval $set_cc_for_build | ||||||
| 	sed 's/^	//' << EOF >$dummy.c | 	sed 's/^	//' << EOF >$dummy.c | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| #include <stdio.h>  /* for printf() prototype */ | #include <stdio.h>  /* for printf() prototype */ | ||||||
| @@ -414,7 +415,6 @@ EOF | |||||||
| 	  exit (-1); | 	  exit (-1); | ||||||
| 	} | 	} | ||||||
| EOF | EOF | ||||||
| 	eval $set_cc_for_build |  | ||||||
| 	$CC_FOR_BUILD $dummy.c -o $dummy \ | 	$CC_FOR_BUILD $dummy.c -o $dummy \ | ||||||
| 	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ | 	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ | ||||||
| 	  && rm -f $dummy.c $dummy && exit 0 | 	  && rm -f $dummy.c $dummy && exit 0 | ||||||
| @@ -484,6 +484,7 @@ EOF | |||||||
| 	exit 0 ;; | 	exit 0 ;; | ||||||
|     *:AIX:2:3) |     *:AIX:2:3) | ||||||
| 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then | 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then | ||||||
|  | 		eval $set_cc_for_build | ||||||
| 		sed 's/^		//' << EOF >$dummy.c | 		sed 's/^		//' << EOF >$dummy.c | ||||||
| 		#include <sys/systemcfg.h> | 		#include <sys/systemcfg.h> | ||||||
|  |  | ||||||
| @@ -495,7 +496,6 @@ EOF | |||||||
| 			exit(0); | 			exit(0); | ||||||
| 			} | 			} | ||||||
| EOF | EOF | ||||||
| 		eval $set_cc_for_build |  | ||||||
| 		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 | 		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 | ||||||
| 		rm -f $dummy.c $dummy | 		rm -f $dummy.c $dummy | ||||||
| 		echo rs6000-ibm-aix3.2.5 | 		echo rs6000-ibm-aix3.2.5 | ||||||
| @@ -563,6 +563,7 @@ EOF | |||||||
|                   fi ;; |                   fi ;; | ||||||
|               esac |               esac | ||||||
|               if [ "${HP_ARCH}" = "" ]; then |               if [ "${HP_ARCH}" = "" ]; then | ||||||
|  | 	      eval $set_cc_for_build | ||||||
|               sed 's/^              //' << EOF >$dummy.c |               sed 's/^              //' << EOF >$dummy.c | ||||||
|  |  | ||||||
|               #define _HPUX_SOURCE |               #define _HPUX_SOURCE | ||||||
| @@ -596,10 +597,9 @@ EOF | |||||||
|                   exit (0); |                   exit (0); | ||||||
|               } |               } | ||||||
| EOF | EOF | ||||||
| 	eval $set_cc_for_build | 	    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` | ||||||
| 	(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` | 	    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi | ||||||
| 	if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi | 	    rm -f $dummy.c $dummy | ||||||
| 	rm -f $dummy.c $dummy |  | ||||||
| 	fi ;; | 	fi ;; | ||||||
| 	esac | 	esac | ||||||
| 	echo ${HP_ARCH}-hp-hpux${HPUX_REV} | 	echo ${HP_ARCH}-hp-hpux${HPUX_REV} | ||||||
| @@ -609,6 +609,7 @@ EOF | |||||||
| 	echo ia64-hp-hpux${HPUX_REV} | 	echo ia64-hp-hpux${HPUX_REV} | ||||||
| 	exit 0 ;; | 	exit 0 ;; | ||||||
|     3050*:HI-UX:*:*) |     3050*:HI-UX:*:*) | ||||||
|  | 	eval $set_cc_for_build | ||||||
| 	sed 's/^	//' << EOF >$dummy.c | 	sed 's/^	//' << EOF >$dummy.c | ||||||
| 	#include <unistd.h> | 	#include <unistd.h> | ||||||
| 	int | 	int | ||||||
| @@ -634,7 +635,6 @@ EOF | |||||||
| 	  exit (0); | 	  exit (0); | ||||||
| 	} | 	} | ||||||
| EOF | EOF | ||||||
| 	eval $set_cc_for_build |  | ||||||
| 	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 | 	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 | ||||||
| 	rm -f $dummy.c $dummy | 	rm -f $dummy.c $dummy | ||||||
| 	echo unknown-hitachi-hiuxwe2 | 	echo unknown-hitachi-hiuxwe2 | ||||||
| @@ -851,6 +851,7 @@ EOF | |||||||
| 		exit 0 ;; | 		exit 0 ;; | ||||||
| 	esac | 	esac | ||||||
| 	# Determine whether the default compiler is a.out or elf | 	# Determine whether the default compiler is a.out or elf | ||||||
|  | 	eval $set_cc_for_build | ||||||
| 	cat >$dummy.c <<EOF | 	cat >$dummy.c <<EOF | ||||||
| #include <features.h> | #include <features.h> | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| @@ -875,7 +876,6 @@ EOF | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| EOF | 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 | 	$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 | 	rm -f $dummy.c $dummy | ||||||
| 	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 | 	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 '(No uname command or uname output not recognized.)' 1>&2 | ||||||
| #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 | #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 | ||||||
|  |  | ||||||
|  | eval $set_cc_for_build | ||||||
| cat >$dummy.c <<EOF | cat >$dummy.c <<EOF | ||||||
| #ifdef _SEQUENT_ | #ifdef _SEQUENT_ | ||||||
| # include <sys/types.h> | # include <sys/types.h> | ||||||
| @@ -1236,7 +1237,6 @@ main () | |||||||
| } | } | ||||||
| EOF | EOF | ||||||
|  |  | ||||||
| eval $set_cc_for_build |  | ||||||
| $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 | $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 | ||||||
| rm -f $dummy.c $dummy | 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 | #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 | ||||||
| #   Free Software Foundation, Inc. | #   Free Software Foundation, Inc. | ||||||
|  |  | ||||||
| timestamp='2001-08-23' | timestamp='2001-09-07' | ||||||
|  |  | ||||||
| # This file is (in principle) common to ALL GNU software. | # This file is (in principle) common to ALL GNU software. | ||||||
| # The presence of a machine in this file suggests that SOME 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 \ | 	| mips16 | mips64 | mips64el | mips64orion | mips64orionel \ | ||||||
| 	| mips64vr4100 | mips64vr4100el | mips64vr4300 \ | 	| mips64vr4100 | mips64vr4100el | mips64vr4300 \ | ||||||
| 	| mips64vr4300el | mips64vr5000 | mips64vr5000el \ | 	| mips64vr4300el | mips64vr5000 | mips64vr5000el \ | ||||||
| 	| mipsbe | mipsel | mipsle | mipstx39 | mipstx39el \ | 	| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ | ||||||
|  | 	| mipsisa32 \ | ||||||
| 	| mn10200 | mn10300 \ | 	| mn10200 | mn10300 \ | ||||||
| 	| ns16k | ns32k \ | 	| ns16k | ns32k \ | ||||||
| 	| openrisc \ | 	| openrisc \ | ||||||
| @@ -293,8 +294,8 @@ case $basic_machine in | |||||||
| 	| m88110-* | m88k-* | mcore-* \ | 	| m88110-* | m88k-* | mcore-* \ | ||||||
| 	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ | 	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ | ||||||
| 	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ | 	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ | ||||||
| 	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipsel-* \ | 	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ | ||||||
| 	| mipsle-* | mipstx39-* | mipstx39el-* \ | 	| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ | ||||||
| 	| none-* | np1-* | ns16k-* | ns32k-* \ | 	| none-* | np1-* | ns16k-* | ns32k-* \ | ||||||
| 	| orion-* \ | 	| orion-* \ | ||||||
| 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								configure.in
									
									
									
									
									
								
							| @@ -1,9 +1,16 @@ | |||||||
| dnl $Id$ | dnl $Id$ | ||||||
| dnl Process this file with autoconf to produce a configure script. | 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_INIT | ||||||
| AC_CONFIG_SRCDIR([lib/urldata.h]) | AC_CONFIG_SRCDIR([lib/urldata.h]) | ||||||
| AM_CONFIG_HEADER(config.h src/config.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` | VERSION=`sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h` | ||||||
| AM_INIT_AUTOMAKE(curl,$VERSION) | AM_INIT_AUTOMAKE(curl,$VERSION) | ||||||
|  |  | ||||||
| @@ -38,6 +45,10 @@ AC_PROG_CC | |||||||
| dnl check for how to do large files | dnl check for how to do large files | ||||||
| AC_SYS_LARGEFILE | AC_SYS_LARGEFILE | ||||||
|  |  | ||||||
|  | dnl check for cygwin stuff | ||||||
|  | AC_LIBTOOL_WIN32_DLL | ||||||
|  |  | ||||||
|  | dnl libtool setup | ||||||
| AM_PROG_LIBTOOL | AM_PROG_LIBTOOL | ||||||
|  |  | ||||||
| dnl The install stuff has already been taken care of by the automake stuff | 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? | dnl dl lib? | ||||||
| AC_CHECK_FUNC(dlclose, , AC_CHECK_LIB(dl, dlopen)) | 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 ********************************************************************** | ||||||
| dnl Check for the random seed preferences  | dnl Check for the random seed preferences  | ||||||
| dnl ********************************************************************** | dnl ********************************************************************** | ||||||
| @@ -428,9 +457,6 @@ then | |||||||
| Set to explicitly specify we don't want to use thread-safe functions) | Set to explicitly specify we don't want to use thread-safe functions) | ||||||
| else | else | ||||||
|  |  | ||||||
|   dnl check that 'localhost' resolves first |  | ||||||
|   CURL_CHECK_WORKING_RESOLVER |  | ||||||
|  |  | ||||||
|   dnl dig around for gethostbyname_r() |   dnl dig around for gethostbyname_r() | ||||||
|   CURL_CHECK_GETHOSTBYNAME_R() |   CURL_CHECK_GETHOSTBYNAME_R() | ||||||
|  |  | ||||||
| @@ -518,7 +544,6 @@ AC_CHECK_FUNCS( socket \ | |||||||
|                 strcmpi \ |                 strcmpi \ | ||||||
|                 gethostname \ |                 gethostname \ | ||||||
|                 gethostbyaddr \ |                 gethostbyaddr \ | ||||||
|                 getservbyname \ |  | ||||||
|                 gettimeofday \ |                 gettimeofday \ | ||||||
|                 inet_addr \ |                 inet_addr \ | ||||||
|                 inet_ntoa \ |                 inet_ntoa \ | ||||||
| @@ -571,6 +596,7 @@ AC_CONFIG_FILES([Makefile \ | |||||||
|            tests/data/Makefile \ |            tests/data/Makefile \ | ||||||
| 	   packages/Makefile \ | 	   packages/Makefile \ | ||||||
| 	   packages/Win32/Makefile \ | 	   packages/Win32/Makefile \ | ||||||
|  | 	   packages/Win32/cygwin/Makefile \ | ||||||
| 	   packages/Linux/Makefile \ | 	   packages/Linux/Makefile \ | ||||||
| 	   packages/Linux/RPM/Makefile \ | 	   packages/Linux/RPM/Makefile \ | ||||||
| 	   packages/Linux/RPM/curl.spec \ | 	   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.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.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? | ||||||
|   3.11 How do I POST with a different Content-Type? |   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. Running Problems | ||||||
|   4.1 Problems connecting to SSL servers. |   4.1 Problems connecting to SSL servers. | ||||||
| @@ -96,10 +97,9 @@ FAQ | |||||||
|  |  | ||||||
|   1.3 What is cURL not? |   1.3 What is cURL not? | ||||||
|    |    | ||||||
|   Curl is *not*, I repeat, *not* a wget clone even though that is a very |   Curl is *not* a wget clone even though that is a very common misconception. | ||||||
|   common misconception. Never, during curl's development, have I intended curl |   Never, during curl's development, have we intended curl to replace wget or | ||||||
|   to replace wget or compete on its market. Curl is targeted at single-shot |   compete on its market. Curl is targeted at single-shot file transfers. | ||||||
|   file transfers. |  | ||||||
|  |  | ||||||
|   Curl is not a web site mirroring program. If you wanna use curl to mirror |   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 |   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 |   * We focus on protocol related issues and improvements. If you wanna do more | ||||||
|     magic with the supported protocols than curl currently does, chances are |     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. |     agree. | ||||||
|  |  | ||||||
|   * If you want someone else to make all the work while you wait for us to |   * 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] |         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. Running Problems | ||||||
|  |  | ||||||
|   4.1. Problems connecting to SSL servers. |   4.1. Problems connecting to SSL servers. | ||||||
| @@ -573,13 +585,7 @@ FAQ | |||||||
|  |  | ||||||
|   5.4 Does libcurl do Winsock initialization on win32 systems? |   5.4 Does libcurl do Winsock initialization on win32 systems? | ||||||
|  |  | ||||||
|   No. |   Yes (since 7.8.1) if told to in the curl_global_init() call. | ||||||
|  |  | ||||||
|   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. |  | ||||||
|  |  | ||||||
|   5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ? |   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. | 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, | Most systems build curl the same way (unix-style). Continue reading below for | ||||||
| you should continue reading from one the paragraphs further down. All other | more details if you're one of them. | ||||||
| systems should be capable of being installed as described below. |  | ||||||
|  | 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 | UNIX | ||||||
| ==== | ==== | ||||||
| @@ -325,13 +328,50 @@ VMS | |||||||
|    13-jul-2001 |    13-jul-2001 | ||||||
|    N. Baggus |    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 | PORTS | ||||||
| ===== | ===== | ||||||
|    This is a probably incomplete list of known hardware and operating systems |    This is a probably incomplete list of known hardware and operating systems | ||||||
|    that curl has been compiled for: |    that curl has been compiled for: | ||||||
|  |  | ||||||
|         - Ultrix 4.3a |  | ||||||
|         - SINIX-Z v5 |  | ||||||
|         - Alpha DEC OSF 4 |         - Alpha DEC OSF 4 | ||||||
|         - Alpha Digital UNIX v3.2 |         - Alpha Digital UNIX v3.2 | ||||||
|         - Alpha FreeBSD 4.1 |         - Alpha FreeBSD 4.1 | ||||||
| @@ -344,9 +384,14 @@ PORTS | |||||||
|         - PowerPC Darwin 1.0 |         - PowerPC Darwin 1.0 | ||||||
|         - PowerPC Linux |         - PowerPC Linux | ||||||
|         - PowerPC Mac OS X |         - PowerPC Mac OS X | ||||||
|  |         - SINIX-Z v5 | ||||||
|         - Sparc Linux |         - Sparc Linux | ||||||
|         - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8 |         - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8 | ||||||
|         - Sparc SunOS 4.1.X |         - 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 BeOS | ||||||
|         - i386 FreeBSD |         - i386 FreeBSD | ||||||
|         - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4 |         - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4 | ||||||
| @@ -359,8 +404,7 @@ PORTS | |||||||
|         - ia64 Linux 2.3.99 |         - ia64 Linux 2.3.99 | ||||||
|         - m68k AmigaOS 3 |         - m68k AmigaOS 3 | ||||||
|         - m68k OpenBSD |         - m68k OpenBSD | ||||||
|         - StrongARM NetBSD 1.4.1 |         - s390 Linux  | ||||||
|         - StrongARM (and other ARM) RISC OS 3.1, 4.02 |  | ||||||
|  |  | ||||||
| OpenSSL | 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. |  makes sure we stay absolutely platform independent. | ||||||
|  |  | ||||||
|  curl_easy_init() allocates an internal struct and makes some initializations. |  curl_easy_init() allocates an internal struct and makes some initializations. | ||||||
|  The returned handle does not reveal internals. This is the 'UrlData' struct |  The returned handle does not reveal internals. This is the 'SessionHandle' | ||||||
|  which works as a global "anchor" struct. All connections performed will get |  struct which works as an "anchor" struct for all curl_easy functions. All | ||||||
|  connect-specific data allocated that should be used for things related to |  connections performed will get connect-specific data allocated that should be | ||||||
|  particular connections/requests. |  used for things related to particular connections/requests. | ||||||
|  |  | ||||||
|  curl_easy_setopt() takes three arguments, where the option stuff must be |  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 |  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 |  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: |  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' |    This function makes sure there's an allocated and initiated 'connectdata' | ||||||
|    struct that is used for this particular connection only (although there may |    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 |    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() |  o Curl_do() | ||||||
|  |  | ||||||
| @@ -123,6 +123,13 @@ Library | |||||||
|    Curl_Transfer() function (in lib/transfer.c) to setup the transfer and |    Curl_Transfer() function (in lib/transfer.c) to setup the transfer and | ||||||
|    returns. |    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() |  o Transfer() | ||||||
|  |  | ||||||
|    Curl_perform() then calls Transfer() in lib/transfer.c that performs |    Curl_perform() then calls Transfer() in lib/transfer.c that performs | ||||||
| @@ -144,7 +151,7 @@ Library | |||||||
|  o Curl_disconnect() |  o Curl_disconnect() | ||||||
|  |  | ||||||
|    When doing normal connections and transfers, no one ever tries to close any |    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 |    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 |    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 |    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 |  The persistent connection support in libcurl requires some considerations on | ||||||
|  how to do things inside of the library. |  how to do things inside of the library. | ||||||
|  |  | ||||||
|  o The 'UrlData' struct returned in the curl_easy_init() call must never |  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 |    hold connection-oriented data. It is meant to hold the root data as well as | ||||||
|    as all the options etc that the library-user may choose. |    all the options etc that the library-user may choose. | ||||||
|  o The 'UrlData' struct holds the "connection cache" (an array of pointers to |  o The 'SessionHandle' struct holds the "connection cache" (an array of | ||||||
|    'connectdata' structs). There's one connectdata struct allocated for each |    pointers to 'connectdata' structs). There's one connectdata struct | ||||||
|    connection that libcurl knows about. |    allocated for each connection that libcurl knows about. | ||||||
|  o This also enables the 'curl handle' to be reused on subsequent transfers, |  o This also enables the 'curl handle' to be reused on subsequent transfers, | ||||||
|    something that was illegal before libcurl 7.7. |    something that was illegal before libcurl 7.7. | ||||||
|  o When we are about to perform a transfer with curl_easy_perform(), we first |  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: |   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: |   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: |   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 |   Note that the http server must've been configured to accept PUT before this | ||||||
|   can be done successfully. |   can be done successfully. | ||||||
| @@ -756,6 +756,17 @@ TELNET | |||||||
|   You might want the -N/--no-buffer option to switch off the buffered output |   You might want the -N/--no-buffer option to switch off the buffered output | ||||||
|   for slow connections or similar. |   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 |   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 |   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 |   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_init.3 \ | ||||||
| 	curl_easy_perform.3 \ | 	curl_easy_perform.3 \ | ||||||
| 	curl_easy_setopt.3 \ | 	curl_easy_setopt.3 \ | ||||||
|  | 	curl_easy_duphandle.3 \ | ||||||
| 	curl_formparse.3 \ | 	curl_formparse.3 \ | ||||||
| 	curl_formadd.3 \ | 	curl_formadd.3 \ | ||||||
| 	curl_formfree.3 \ | 	curl_formfree.3 \ | ||||||
| @@ -39,6 +40,7 @@ HTMLPAGES = \ | |||||||
| 	curl_easy_init.html \ | 	curl_easy_init.html \ | ||||||
| 	curl_easy_perform.html \ | 	curl_easy_perform.html \ | ||||||
| 	curl_easy_setopt.html \ | 	curl_easy_setopt.html \ | ||||||
|  | 	curl_easy_duphandle.html \ | ||||||
| 	curl_formadd.html \ | 	curl_formadd.html \ | ||||||
| 	curl_formparse.html \ | 	curl_formparse.html \ | ||||||
| 	curl_formfree.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 |  send me patches that improve things! Also check the http://curl.haxx.se/dev | ||||||
|  web section for various development notes. |  web section for various development notes. | ||||||
|  |  | ||||||
| To do in a future release (random order): |  LIBCURL | ||||||
|  |  | ||||||
|  * 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  |  | ||||||
|  |  | ||||||
|  * Consider an interface to libcurl that allows applications to easier get to |  * Consider an interface to libcurl that allows applications to easier get to | ||||||
|    know what cookies that are sent back in the response headers. |    know what cookies that are sent back in the response headers. | ||||||
|  |  | ||||||
|  * HTTP PUT for files passed on stdin. Requires libcurl to send the file |  * Make content encoding/decoding internally be made using a filter system. | ||||||
|    with chunked content encoding. http://curl.haxx.se/dev/HTTP-PUT-stdin.txt |  | ||||||
|  |  * 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 |  * Introduce another callback interface for upload/download that makes one | ||||||
|    less copy of data and thus a faster operation. |    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 |  * 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 |    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...! |  * Suggested on the mailing list: CURLOPT_FTP_MKDIR...! | ||||||
|  |  | ||||||
|  * Add configure options that disables certain protocols in libcurl to |  * Always use the FTP SIZE command before downloading, as that makes it more | ||||||
|    decrease footprint.  '--disable-[protocol]' where protocol is http, ftp, |    likely that we know the size when downloading. Some sites support SIZE but | ||||||
|    telnet, ldap, dict or file. |    don't show the size in the RETR response! | ||||||
|  |  | ||||||
|  * Extend the test suite to include telnet. The telnet could just do ftp or |  * Make FTP PASV work with IPv6 support. RFC 2428 "FTP Extensions for IPv6 and | ||||||
|    http operations (for which we have test servers). |    NATs" is interesting. | ||||||
|  |  | ||||||
|  * Make TELNET work on windows! |  HTTP | ||||||
|  |  | ||||||
|  * Make curl's SSL layer option capable of using other free SSL libraries. |  * HTTP PUT for files passed on stdin *OR* when the --crlf option is | ||||||
|    Such as the Mozilla Security Services |    used. Requires libcurl to send the file with chunked content | ||||||
|    (http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS |    encoding. [http://curl.haxx.se/dev/HTTP-PUT-stdin.txt] When the filter | ||||||
|    (http://gnutls.hellug.gr/) |    system mentioned above gets real, it'll be a piece of cake to add. | ||||||
|  |  | ||||||
|  * 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? |  | ||||||
|  |  | ||||||
|  * "Content-Encoding: compress/gzip/zlib" HTTP 1.1 clearly defines how to get |  * "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 |    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 |    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 |    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: NTLM. Support for that MS crap called NTLM | ||||||
|    authentication. MS proxies and servers sometime require that. Since that |    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 |    sends the password in cleartext over the network, this "Digest" method uses | ||||||
|    a challange-response protocol which increases security quite a lot. |    a challange-response protocol which increases security quite a lot. | ||||||
|  |  | ||||||
|  * Other proxies |  TELNET | ||||||
|    Ftp-kind proxy, Socks5, whatever kind of proxies are there? |  | ||||||
|  |  | ||||||
|  * Full IPv6 Awareness and support. (This is partly done.)  RFC 2428 "FTP |  * Make TELNET work on windows98! | ||||||
|    Extensions for IPv6 and NATs" is interesting. PORT should be replaced with |  | ||||||
|    EPRT for IPv6 (done), and EPSV instead of PASV. |  | ||||||
|  |  | ||||||
|  |  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 | Online:  http://curl.haxx.se/docs/httpscripting.shtml | ||||||
| Author:  Daniel Stenberg <daniel@haxx.se> | Author:  Daniel Stenberg <daniel@haxx.se> | ||||||
| Date:    August 20, 2001 | Date:    October 31, 2001 | ||||||
| Version: 0.4 | Version: 0.5 | ||||||
|  |  | ||||||
|                 The Art Of Scripting HTTP Requests Using Curl |                 The Art Of Scripting HTTP Requests Using Curl | ||||||
|                 ============================================= |                 ============================================= | ||||||
| @@ -48,7 +48,7 @@ Version: 0.4 | |||||||
| 2. URL | 2. URL | ||||||
|  |  | ||||||
|  The Uniform Resource Locator format is how you specify the address of a |  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. |  http://curl.haxx.se or https://yourbank.com a million times. | ||||||
|  |  | ||||||
| 3. GET a page | 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 |  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 |  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. |  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 |         curl http://curl.haxx.se | ||||||
|  |  | ||||||
| @@ -89,7 +89,7 @@ Version: 0.4 | |||||||
|           <input type=submit name=press value="OK"> |           <input type=submit name=press value="OK"> | ||||||
|         </form> |         </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 |   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 |   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 |   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 |  4.3 FILE UPLOAD POST | ||||||
|  |  | ||||||
|   Back in late 1995 they defined a new way to post data over HTTP. It was |   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 |   documented in the RFC 1867, why this method sometimes is referred to as | ||||||
|   a rfc1867-posting. |   a RFC1867-posting. | ||||||
|  |  | ||||||
|   This method is mainly designed to better support file uploads. A form that |   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: |   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. |   way your browser does. | ||||||
|  |  | ||||||
|   An easy way to get to see this, is to save the HTML page with the form on |   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 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 |   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 |  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 |  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 |  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 |         curl -U proxyuser:proxypassword curl.haxx.se | ||||||
|  |  | ||||||
| @@ -294,7 +294,7 @@ Version: 0.4 | |||||||
|  contents to the server, unless of course they are expired. |  contents to the server, unless of course they are expired. | ||||||
|  |  | ||||||
|  Many applications and servers use this method to connect a series of requests |  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 |  must be able to record and send back cookies the way the web application | ||||||
|  expects them. The same way browsers deal with them. |  expects them. The same way browsers deal with them. | ||||||
|  |  | ||||||
| @@ -325,6 +325,15 @@ Version: 0.4 | |||||||
|  |  | ||||||
|         curl -b nada -L www.cookiesite.com |         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 | 11. HTTPS | ||||||
|  |  | ||||||
|  There are a few ways to do secure HTTP transfers. The by far most common |  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 |   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 |   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 |   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 |         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 |  RFC 2616 is a must to read if you want in-depth understanding of the HTTP | ||||||
|  protocol. |  protocol. | ||||||
|  |  | ||||||
|  RFC 2396 explains the URL syntax |  RFC 2396 explains the URL syntax. | ||||||
|  |  | ||||||
|  RFC 2109 defines how cookies are supposed to work. |  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://www.openssl.org is the home of the OpenSSL project | ||||||
|  |  | ||||||
|  http://curl.haxx.se is the home of the cURL 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 | .\" nroff -man curl.1 | ||||||
| .\" Written by Daniel Stenberg | .\" 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 | .SH NAME | ||||||
| curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or | curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or | ||||||
| HTTPS syntax. | HTTPS syntax. | ||||||
| @@ -485,14 +485,15 @@ XDISPLOC=<X display> Sets the X display location. | |||||||
|  |  | ||||||
| NEW_ENV=<var,val> Sets an environment variable. | NEW_ENV=<var,val> Sets an environment variable. | ||||||
| .IP "-T/--upload-file <file>" | .IP "-T/--upload-file <file>" | ||||||
| Like -t, but this transfers the specified local file. If there is no | This transfers the specified local file to the remote URL. If there is no file | ||||||
| file part in the specified URL, Curl will append the local file | part in the specified URL, Curl will append the local file name. NOTE that you | ||||||
| name. NOTE that you must use a trailing / on the last directory to | must use a trailing / on the last directory to really prove to Curl that there | ||||||
| really prove to Curl that there is no file name or curl will | is no file name or curl will think that your last directory name is the remote | ||||||
| think that your last directory name is the remote file name to | file name to use. That will most likely cause the upload operation to fail. If | ||||||
| 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. | 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. | If this option is used several times, the last one will be used. | ||||||
| .IP "-u/--user <user:password>" | .IP "-u/--user <user:password>" | ||||||
| Specify user and password to use when fetching. See README.curl for detailed | 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. | If this option is used several times, the last one will be used. | ||||||
| .IP "-x/--proxy <proxyhost[:port]>" | .IP "-x/--proxy <proxyhost[:port]>" | ||||||
| Use specified proxy. If the port number is not specified, it is assumed at | Use specified HTTP proxy. If the port number is not specified, it is assumed | ||||||
| port 1080. | 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. | If this option is used several times, the last one will be used. | ||||||
| .IP "-X/--request <command>" | .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" | .IP "-2/--sslv2" | ||||||
| (HTTPS) | (HTTPS) | ||||||
| Forces curl to use SSL version 2 when negotiating with a remote SSL server. | 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" | .IP "-#/--progress-bar" | ||||||
| Make curl display progress information as a progress bar instead of the | Make curl display progress information as a progress bar instead of the | ||||||
| default statistics. | 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] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $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 | .SH NAME | ||||||
| curl_easy_setopt - Set curl easy-session options | curl_easy_setopt - Set curl easy-session options | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| .B #include <curl/curl.h> | #include <curl/curl.h> | ||||||
| .sp |  | ||||||
| .BI "CURLcode curl_easy_setopt(CURL *" handle ", CURLoption "option ", ...);" | CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter); | ||||||
| .ad | .ad | ||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| curl_easy_setopt() is called to tell libcurl how to behave in a number of | curl_easy_setopt() is used to tell libcurl how to behave. Most operations in | ||||||
| ways. Most operations in libcurl have default actions, and by using the | libcurl have default actions, and by using the appropriate options to | ||||||
| appropriate options you can make them behave differently (as documented).  All | \fIcurl_easy_setopt\fP, you can change them.  All options are set with the | ||||||
| options are set with the | \fIoption\fP followed by a \fIparameter\fP. That parameter can be a long, a | ||||||
| .I option | function pointer or an object pointer, all depending on what the specific | ||||||
| followed by a parameter. That parameter can be a long, a function pointer or | option expects. Read this manual carefully as bad input values may cause | ||||||
| an object pointer, all depending on what the option in question expects. Read | libcurl to behave badly!  You can only set one option in each function call. A | ||||||
| this manual carefully as bad input values may cause libcurl to behave badly! | typical application uses many curl_easy_setopt() calls in the setup phase. | ||||||
| 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 | \fBNOTE:\fP strings passed to libcurl as 'char *' arguments, will not be | ||||||
| the library. Instead you should keep them available until libcurl no longer | copied by the library. Instead you should keep them available until libcurl no | ||||||
| needs them. Failing to do so will cause very odd behaviour or even crashes. | 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 | \fBNOTE2:\fP options set with this function call are valid for the forthcoming | ||||||
| forthcoming data transfers that are performed when you invoke | data transfers that are performed when you invoke \fIcurl_easy_perform\fP. | ||||||
| .I curl_easy_perform . |  | ||||||
| The options are not in any way reset between transfers, so if you want | 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 | subsequent transfers with different options, you must change them between the | ||||||
| transfers. | transfers. | ||||||
|  |  | ||||||
| The | The \fIhandle\fP is the return code from a \fIcurl_easy_init(3)\fP or | ||||||
| .I "handle" | \fIcurl_easy_duphandle(3)\fP call. | ||||||
| is the return code from the |  | ||||||
| .I "curl_easy_init" |  | ||||||
| call. |  | ||||||
| .SH OPTIONS | .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 | .TP 0.8i | ||||||
| .B CURLOPT_FILE | .B CURLOPT_FILE | ||||||
| Data pointer to pass to file write function. Note that if you specify the | Data pointer to pass to the file write function. Note that if you specify the | ||||||
| .I CURLOPT_WRITEFUNCTION | \fICURLOPT_WRITEFUNCTION\fP, this is the pointer you'll get as input. If you | ||||||
| , this is the pointer you'll get as input. If you don't use a callback, you | don't use a callback, you must pass a 'FILE *' as libcurl will pass this to | ||||||
| must pass a 'FILE *' as libcurl passes it to fwrite() when writing data. | fwrite() when writing data. | ||||||
|  |  | ||||||
| NOTE: If you're using libcurl as a win32 DLL, you MUST use the | \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use the | ||||||
| \fICURLOPT_WRITEFUNCTION\fP if you set this option. | \fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience | ||||||
|  | crashes. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_WRITEFUNCTION | .B CURLOPT_WRITEFUNCTION | ||||||
| Function pointer that should match the following prototype: | Function pointer that should match the following prototype: \fBsize_t | ||||||
| .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);" | function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This | ||||||
| This function gets called by libcurl as soon as there is received data that | function gets called by libcurl as soon as there is data available to pass | ||||||
| needs to be written down. The size of the data pointed to by \fIptr\fP is | available that needs to be saved. The size of the data pointed to by \fIptr\fP | ||||||
| \fIsize\fP multiplied with \fInmemb\fP.  Return the number of bytes actually | is \fIsize\fP multiplied with \fInmemb\fP.  Return the number of bytes | ||||||
| written or return -1 to signal error to the library (it will cause it to abort | actually taken care of. If that amount differs from the amount passed to your | ||||||
| the transfer with CURLE_WRITE_ERROR). | 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. | 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 | .TP | ||||||
| .B CURLOPT_INFILE | .B CURLOPT_INFILE | ||||||
| Data pointer to pass to the file read function. Note that if you specify the | 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 | \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 *. | 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. | \fICURLOPT_READFUNCTION\fP if you set this option. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_READFUNCTION | .B CURLOPT_READFUNCTION | ||||||
| Function pointer that should match the following prototype: | Function pointer that should match the following prototype: \fBsize_t | ||||||
| .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);" | function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This | ||||||
| This function gets called by libcurl as soon as it needs to read data in order | function gets called by libcurl as soon as it needs to read data in order to | ||||||
| to send it to the peer. The data area pointed at by the pointer \fIptr\fP may | send it to the peer. The data area pointed at by the pointer \fIptr\fP may be | ||||||
| be filled with at most \fIsize\fP multiplied with \fInmemb\fP number of | 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 | 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 | 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 | it to abort the current transfer immediately (with a \fICURLE_READ_ERROR\fP | ||||||
| code). | return code). | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_INFILESIZE | .B CURLOPT_INFILESIZE | ||||||
| When uploading a file to a remote site, this option should be used to tell | 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 | .B CURLOPT_URL | ||||||
| The actual URL to deal with. The parameter should be a char * to a zero | 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 | 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 | it, as it doesn't copy the string. | ||||||
| before curl_easy_perform() is called. |  | ||||||
|  | \fBNOTE:\fP this option is (the only one) required to be set before | ||||||
|  | \fIcurl_easy_perform(3)\fP is called. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_PROXY | .B CURLOPT_PROXY | ||||||
| If you need libcurl to use a http proxy to access the outside world, set the | Set HTTP proxy to use. The parameter should be a char * to a zero terminated | ||||||
| proxy string with this option. The parameter should be a char * to a zero | string holding the host name or dotted IP address. To specify port number in | ||||||
| terminated string. To specify port number in this string, append :[port] to | this string, append :[port] to the end of the host name. The proxy string may | ||||||
| the end of the host name. The proxy string may be prefixed with | be prefixed with [protocol]:// since any such prefix will be ignored. The | ||||||
| [protocol]:// since any such prefix will be ignored. | 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 | .TP | ||||||
| .B CURLOPT_PROXYPORT | .B CURLOPT_PROXYPORT | ||||||
| Set this long with this option to set the proxy port to use unless it is | Pass a long with this option to set the proxy port to connect to unless it is | ||||||
| specified in the proxy string CURLOPT_PROXY. | specified in the proxy string \fICURLOPT_PROXY\fP. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_HTTPPROXYTUNNEL | .B CURLOPT_HTTPPROXYTUNNEL | ||||||
| Set the parameter to non-zero to get the library to tunnel all non-HTTP | Set the parameter to non-zero to get the library to tunnel all operations | ||||||
| operations through the given HTTP proxy. Do note that there is a big | through a given HTTP proxy. Note that there is a big difference between using | ||||||
| difference to use a proxy and to tunnel through it. If you don't know what | a proxy and to tunnel through it. If you don't know what this means, you | ||||||
| this means, you probably don't want this tunnel option. (Added in libcurl 7.3) | probably don't want this tunneling option. (Added in libcurl 7.3) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_VERBOSE | .B CURLOPT_VERBOSE | ||||||
| Set the parameter to non-zero to get the library to display a lot of 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. | debugging and understanding. | ||||||
|  |  | ||||||
|  | You hardly ever want this set in production use, you will almost always want | ||||||
|  | this when you debug/report problems. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_HEADER | .B CURLOPT_HEADER | ||||||
| A non-zero parameter tells the library to include the header in the | A non-zero parameter tells the library to include the header in the body | ||||||
| output. This is only relevant for protocols that actually has a header | output. This is only relevant for protocols that actually have headers | ||||||
| preceeding the data (like HTTP). | preceding the data (like HTTP). | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_NOPROGRESS | .B CURLOPT_NOPROGRESS | ||||||
| A non-zero parameter tells the library to shut of the built-in progress meter | 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 | completely. | ||||||
| built-in progress meter at all). |  | ||||||
|  | \fBNOTE:\fP future versions of libcurl is likely to not have any built-in | ||||||
|  | progress meter at all. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_NOBODY | .B CURLOPT_NOBODY | ||||||
| A non-zero parameter tells the library to not include the body-part in the | 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 | output. This is only relevant for protocols that have separate header and body | ||||||
| body part. | parts. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FAILONERROR | .B CURLOPT_FAILONERROR | ||||||
| A non-zero parameter tells the library to fail silently if the HTTP code | 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. | the page normally, ignoring that code. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_UPLOAD | .B CURLOPT_UPLOAD | ||||||
| @@ -146,7 +165,7 @@ will imply this option. | |||||||
| .TP | .TP | ||||||
| .B CURLOPT_FTPLISTONLY | .B CURLOPT_FTPLISTONLY | ||||||
| A non-zero parameter tells the library to just list the names of an ftp | 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. | sizes, dates etc. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FTPAPPEND | .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. | overwrite it. This is only useful when uploading to a ftp site. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_NETRC | .B CURLOPT_NETRC | ||||||
| A non-zero parameter tells the library to scan your | A non-zero parameter tells the library to scan your \fI~/.netrc\fP file to | ||||||
| .I ~/.netrc | find user name and password for the remote site you are about to access. Only | ||||||
| file to find user name and password for the remote site you are about to | machine name, user name and password is taken into account (init macros and | ||||||
| access. Do note that curl does not verify that the file has the correct | similar things aren't supported). | ||||||
| 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 | \fBNote:\fP libcurl does not verify that the file has the correct properties | ||||||
| things aren't supported). | set (as the standard Unix ftp client does). It should only be readable by | ||||||
|  | user. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FOLLOWLOCATION | .B CURLOPT_FOLLOWLOCATION | ||||||
| A non-zero parameter tells the library to follow any Location: header that the | 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 | server sends as part of a HTTP header. | ||||||
| will resend the same request on the new location and follow new Location: |  | ||||||
| headers all the way until no more such headers are returned. | \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 | .TP | ||||||
| .B CURLOPT_TRANSFERTEXT | .B CURLOPT_TRANSFERTEXT | ||||||
| A non-zero parameter tells the library to use ASCII mode for ftp transfers, | 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 | 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 | 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 | binary mode. This option can be usable when transferring text data between | ||||||
| system with different views on certain characters, such as newlines or | systems with different views on certain characters, such as newlines or | ||||||
| similar. | similar. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_PUT | .B CURLOPT_PUT | ||||||
| A non-zero parameter tells the library to use HTTP PUT a file. The file to put | A non-zero parameter tells the library to use HTTP PUT to transfer data. The | ||||||
| must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE. | data should be set with CURLOPT_INFILE and CURLOPT_INFILESIZE. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_USERPWD | .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. | 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 | .TP | ||||||
| .B CURLOPT_PROXYUSERPWD | .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 | 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 | .TP | ||||||
| .B CURLOPT_RANGE | .B CURLOPT_RANGE | ||||||
| Pass a char * as parameter, which should contain the specified range you | 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 | 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 | transfers also support several intervals, separated with commas as in | ||||||
| .I "X-Y,N-M" | \fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP | ||||||
| . Using this kind of multiple intervals will cause the HTTP server to send the | server to send the response document in pieces (using standard MIME separation | ||||||
| response document in pieces. | techniques). | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_ERRORBUFFER | .B CURLOPT_ERRORBUFFER | ||||||
| Pass a char * to a buffer that the libcurl may store human readable error | 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 | 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. | 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 | .TP | ||||||
| .B CURLOPT_TIMEOUT | .B CURLOPT_TIMEOUT | ||||||
| Pass a long as parameter containing the maximum time in seconds that you allow | 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 | the libcurl transfer operation to take. Normally, name lookups can take a | ||||||
| considerable time and limiting operations to less than a few minutes risk | considerable time and limiting operations to less than a few minutes risk | ||||||
| aborting perfectly normal operations. This option will cause curl to use the | aborting perfectly normal operations. This option will cause curl to use the | ||||||
| SIGALRM to enable timeouting system calls. | SIGALRM to enable time-outing system calls. | ||||||
| .B NOTE |  | ||||||
| that this does not work in multi-threaded programs! | \fBNOTE:\fP this does not work in Unix multi-threaded programs, as it uses | ||||||
|  | signals. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_POSTFIELDS | .B CURLOPT_POSTFIELDS | ||||||
| Pass a char * as parameter, which should be the full data to post in a HTTP | 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 | post operation. This is a normal application/x-www-form-urlencoded kind, which | ||||||
| implies CURLOPT_POST. | 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 | .TP | ||||||
| .B CURLOPT_POSTFIELDSIZE | .B CURLOPT_POSTFIELDSIZE | ||||||
| If you want to post data to the server without letting libcurl do a strlen() | 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 | to measure the data size, this option must be used. When this option is used | ||||||
| used, you can post fully binary data which otherwise is likely to fail. If | you can post fully binary data, which otherwise is likely to fail. If this | ||||||
| this size is set to zero, the library will use strlen() to get the data | size is set to zero, the library will use strlen() to get the size. (Added in | ||||||
| size. (Added in libcurl 7.2) | libcurl 7.2) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_REFERER | .B CURLOPT_REFERER | ||||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | Pass a pointer to a zero terminated string as parameter. It will be used to | ||||||
| set the referer: header in the http request sent to the remote server. This | set the Referer: header in the http request sent to the remote server. This | ||||||
| can be used to fool servers or scripts. | can be used to fool servers or scripts. You can also set any custom header | ||||||
|  | with \fICURLOPT_HTTPHEADER\fP. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_USERAGENT | .B CURLOPT_USERAGENT | ||||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | Pass a pointer to a zero terminated string as parameter. It will be used to | ||||||
| set the user-agent: header in the http request sent to the remote server. This | set the User-Agent: header in the http request sent to the remote server. This | ||||||
| can be used to fool servers or scripts. | can be used to fool servers or scripts. You can also set any custom header | ||||||
|  | with \fICURLOPT_HTTPHEADER\fP. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FTPPORT | .B CURLOPT_FTPPORT | ||||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | Pass a pointer to a zero terminated string as parameter. It will be used to | ||||||
| get the IP address to use for the ftp PORT instruction. The PORT instruction | 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 | 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 | 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. | 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 | .TP | ||||||
| .B CURLOPT_LOW_SPEED_LIMIT | .B CURLOPT_LOW_SPEED_LIMIT | ||||||
| Pass a long as parameter. It contains the transfer speed in bytes per second | 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 | .TP | ||||||
| .B CURLOPT_HTTPHEADER | .B CURLOPT_HTTPHEADER | ||||||
| Pass a pointer to a linked list of HTTP headers to pass to the server in your | 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 | HTTP request. The linked list should be a fully valid list of \fBstruct | ||||||
| curl_slist' structs properly filled in. Use | curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to | ||||||
| .I curl_slist_append(3) | create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire | ||||||
| to create the list and | list. If you add a header that is otherwise generated and used by libcurl | ||||||
| .I curl_slist_free_all(3) | internally, your added one will be used instead. If you add a header with no | ||||||
| to clean up an entire list. If you add a header that is otherwise generated | contents as in 'Accept:' (no data on the right side of the colon), the | ||||||
| and used by libcurl internally, your added one will be used instead. If you | internally used header will get disabled. Thus, using this option you can add | ||||||
| add a header with no contents as in 'Accept:', the internally used header will | new headers, replace internal headers and remove internal headers. | ||||||
| just 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 | .TP | ||||||
| .B CURLOPT_HTTPPOST | .B CURLOPT_HTTPPOST | ||||||
| Tells libcurl you want a multipart/formdata HTTP POST to be made and you | 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 | 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 | 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 | list of 'struct HttpPost' structs properly filled in. The best and most | ||||||
| elegant way to do this, is to use | elegant way to do this, is to use \fIcurl_formadd(3)\fP as documented. The | ||||||
| .I curl_formadd(3) | data in this list must remained intact until you close this curl handle again | ||||||
| as documented. The data in this list must remained intact until you close this | with \fIcurl_easy_cleanup(3)\fP. | ||||||
| curl handle again with curl_easy_cleanup(). |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_SSLCERT | .B CURLOPT_SSLCERT | ||||||
| Pass a pointer to a zero terminated string as parameter. The string should be | 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 | .TP | ||||||
| .B CURLOPT_SSLCERTPASSWD | .B CURLOPT_SSLCERTPASSWD | ||||||
| Pass a pointer to a zero terminated string as parameter. It will be used as | 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 | 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 | .TP | ||||||
| .B CURLOPT_CRLF | .B CURLOPT_CRLF | ||||||
| Convert unix newlines to CRLF newlines on FTP uploads. | Convert Unix newlines to CRLF newlines on FTP uploads. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_QUOTE | .B CURLOPT_QUOTE | ||||||
| Pass a pointer to a linked list of FTP commands to pass to the server prior to | Pass a pointer to a linked list of FTP commands to pass to the server prior to | ||||||
| your ftp request. The linked list should be a fully valid list of 'struct | your ftp request. The linked list should be a fully valid list of 'struct | ||||||
| curl_slist' structs properly filled in. Use | curl_slist' structs properly filled in. Use \fIcurl_slist_append(3)\fP to | ||||||
| .I curl_slist_append(3) | append strings (commands) to the list, and clear the entire list afterwards | ||||||
| to append strings (commands) to the list, and clear the entire list afterwards | with \fIcurl_slist_free_all(3)\fP. | ||||||
| with |  | ||||||
| .I curl_slist_free_all(3) |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_POSTQUOTE | .B CURLOPT_POSTQUOTE | ||||||
| Pass a pointer to a linked list of FTP commands to pass to the server after | Pass a pointer to a linked list of FTP commands to pass to the server after | ||||||
| your ftp transfer request. The linked list should be a fully valid list of | your ftp transfer request. The linked list should be a fully valid list of | ||||||
| struct curl_slist structs properly filled in as described for | struct curl_slist structs properly filled in as described for | ||||||
| .I "CURLOPT_QUOTE" | \fICURLOPT_QUOTE\fP. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_WRITEHEADER | .B CURLOPT_WRITEHEADER | ||||||
| Pass a pointer to be used to write the header part of the received data to. If | 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 | you don't use your own callback to take care of the writing, this must be a | ||||||
| *. The headers are guaranteed to be written one-by-one and only complete lines | valid FILE *. See also the \fICURLOPT_HEADERFUNCTION\fP option below on how to set a | ||||||
| are written. Parsing headers should be easy enough using this. See also the | custom get-all-headers callback. | ||||||
| \fICURLOPT_HEADERFUNCTION\fP option. |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_HEADERFUNCTION | .B CURLOPT_HEADERFUNCTION | ||||||
| Function pointer that should match the following prototype: | Function pointer that should match the following prototype: \fIsize_t | ||||||
| .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);" | function( void *ptr, size_t size, size_t nmemb, void *stream);\fP. This | ||||||
| This function gets called by libcurl as soon as there is received header data | function gets called by libcurl as soon as there is received header data that | ||||||
| that needs to be written down. The function will be called once for each | needs to be written down. The headers are guaranteed to be written one-by-one | ||||||
| header with a complete header line in each invoke. The size of the data | and only complete lines are written. Parsing headers should be easy enough | ||||||
| pointed to by | using this. The size of the data pointed to by \fIptr\fP is \fIsize\fP | ||||||
| .I ptr  | multiplied with \fInmemb\fP.  The pointer named \fIstream\fP will be the one | ||||||
| is | you passed to libcurl with the \fICURLOPT_WRITEHEADER\fP option.  Return the | ||||||
| .I size | number of bytes actually written or return -1 to signal error to the library | ||||||
| multiplied with | (it will cause it to abort the transfer with a \fICURLE_WRITE_ERROR\fP return | ||||||
| .I nmemb. | code). (Added in libcurl 7.7.2) | ||||||
| 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) |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_COOKIEFILE | .B CURLOPT_COOKIEFILE | ||||||
| Pass a pointer to a zero terminated string as parameter. It should contain the | Pass a pointer to a zero terminated string as parameter. It should contain the | ||||||
| @@ -347,12 +372,12 @@ file. | |||||||
| .B CURLOPT_SSLVERSION | .B CURLOPT_SSLVERSION | ||||||
| Pass a long as parameter. Set what version of SSL to attempt to use, 2 or | 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 | 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 | .TP | ||||||
| .B CURLOPT_TIMECONDITION | .B CURLOPT_TIMECONDITION | ||||||
| Pass a long as parameter. This defines how the CURLOPT_TIMEVALUE time value is | Pass a long as parameter. This defines how the CURLOPT_TIMEVALUE time value is | ||||||
| treated. You can set this parameter to TIMECOND_IFMODSINCE or | 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 | .TP | ||||||
| .B CURLOPT_TIMEVALUE | .B CURLOPT_TIMEVALUE | ||||||
| Pass a long as parameter. This should be the time in seconds since 1 jan 1970, | 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 | .B CURLOPT_CUSTOMREQUEST | ||||||
| Pass a pointer to a zero terminated string as parameter. It will be user | Pass a pointer to a zero terminated string as parameter. It will be user | ||||||
| instead of GET or HEAD when doing the HTTP request. This is useful for doing | instead of GET or HEAD when doing the HTTP request. This is useful for doing | ||||||
| DELETE or other more obscure HTTP requests. Don't do this at will, make sure | DELETE or other more or less obscure HTTP requests. Don't do this at will, | ||||||
| your server supports the command first. | make sure your server supports the command first. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_STDERR | .B CURLOPT_STDERR | ||||||
| Pass a FILE * as parameter. This is the stream to use instead of 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 | will be used. Set the string to NULL to disable kerberos4. The kerberos | ||||||
| support only works for FTP. (Added in libcurl 7.3) | support only works for FTP. (Added in libcurl 7.3) | ||||||
| .TP | .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 | .B CURLOPT_PROGRESSFUNCTION | ||||||
| Function pointer that should match the | Function pointer that should match the \fIcurl_progress_callback\fP prototype | ||||||
| .BI curl_progress_callback | found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of | ||||||
| prototype found in | its internal equivalent with a frequent interval during data transfer. | ||||||
| .I <curl/curl.h> | Unknown/unused argument values will be set to zero (like if you only download | ||||||
| This function gets called by libcurl instead of its internal | data, the upload size will remain 0). Returning a non-zero value from this | ||||||
| equivalent. Unknown/unused argument values will be set to zero (like if you | callback will cause libcurl to abort the transfer and return | ||||||
| only download data, the upload size will remain 0). Returning a non-zero value | \fICURLE_ABORTED_BY_CALLBACK\fP. | ||||||
| from this callback will cause libcurl to abort the transfer and return |  | ||||||
| CURLE_ABORTED_BY_CALLBACK. |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_PROGRESSDATA | .B CURLOPT_PROGRESSDATA | ||||||
| Pass a pointer that will be untouched by libcurl and passed as the first | Pass a pointer that will be untouched by libcurl and passed as the first | ||||||
| argument in the progress callback set with | argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP. | ||||||
| .I CURLOPT_PROGRESSFUNCTION |  | ||||||
|  . |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_SSL_VERIFYPEER | .B CURLOPT_SSL_VERIFYPEER | ||||||
| Pass a long that is set to a non-zero value to make curl verify the peer's | 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) | CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_PASSWDFUNCTION | .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 | instead of the internal one if libcurl requests a password. The function must | ||||||
| match this prototype: | match this prototype: \fBint my_getpass(void *client, char *prompt, char* | ||||||
| .BI "int my_getpass(void *client, char *prompt, char* buffer, int buflen );" | buffer, int buflen );\fP.  If set to NULL, it equals to making the function | ||||||
| If set to NULL, it equals to making the function always fail. If the function | always fail. If the function returns a non-zero value, it will abort the | ||||||
| returns a non-zero value, it will abort the operation and an error | operation and an error (CURLE_BAD_PASSWORD_ENTERED) will be returned. | ||||||
| (CURLE_BAD_PASSWORD_ENTERED) will be returned. | \fIclient\fP is a generic pointer, see \fICURLOPT_PASSWDDATA\fP.  \fIprompt\fP | ||||||
| .I client |  | ||||||
| is a generic pointer, see CURLOPT_PASSWDDATA. |  | ||||||
| .I prompt |  | ||||||
| is a zero-terminated string that is text that prefixes the input request. | is a zero-terminated string that is text that prefixes the input request. | ||||||
| .I buffer | \fIbuffer\fP is a pointer to data where the entered password should be stored | ||||||
| is a pointer to data where the entered password should be stored and | and \fIbuflen\fP is the maximum number of bytes that may be written in the | ||||||
| .I buflen | buffer.  (Added in 7.4.2) | ||||||
| is the maximum number of bytes that may be written in the buffer. |  | ||||||
| (Added in 7.4.2) |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_PASSWDDATA | .B CURLOPT_PASSWDDATA | ||||||
| Pass a void * to whatever data you want. The passed pointer will be the first | 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) | 7.4.2) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FILETIME | .B CURLOPT_FILETIME | ||||||
| Pass a long. If it is a non-zero value, libcurl will attempt to get the | Pass a long. If it is a non-zero value, libcurl will attempt to get the | ||||||
| modification date of the remote document in this operation. This requires that | 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 | 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 | \fIcurl_easy_getinfo(3)\fP function with the \fICURLINFO_FILETIME\fP argument | ||||||
| after a transfer to extract the received time (if any). (Added in 7.5) | can be used after a transfer to extract the received time (if any). (Added in | ||||||
|  | 7.5) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_MAXREDIRS | .B CURLOPT_MAXREDIRS | ||||||
| Pass a long. The set number will be the redirection limit. If that many | 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 | redirections have been followed, the next redirect will cause an error | ||||||
| option only makes sense if the CURLOPT_FOLLOWLOCATION is used at the same | (\fICURLE_TOO_MANY_REDIRECTS\fP). This option only makes sense if the | ||||||
| time. (Added in 7.5) | \fICURLOPT_FOLLOWLOCATION\fP is used at the same time. (Added in 7.5) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_MAXCONNECTS | .B CURLOPT_MAXCONNECTS | ||||||
| Pass a long. The set number will be the persistant connection cache size. The | 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 | 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 | 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 | changing this value unless you are perfectly aware of how this work and | ||||||
| changes libcurl's behaviour. Note: if you have already performed transfers | changes libcurl's behaviour. | ||||||
| with this curl handle, setting a smaller MAXCONNECTS than before may cause |  | ||||||
| open connections to unnecessarily get closed. (Added in 7.7) | \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 | .TP | ||||||
| .B CURLOPT_CLOSEPOLICY | .B CURLOPT_CLOSEPOLICY | ||||||
| Pass a long. This option sets what policy libcurl should use when the | 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 | 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_* | make room for a new connection. This must be one of the CURLCLOSEPOLICY_* | ||||||
| defines. Use CURLCLOSEPOLICY_LEAST_RECENTLY_USED to make libcurl close the | defines. Use \fICURLCLOSEPOLICY_LEAST_RECENTLY_USED\fP to make libcurl close | ||||||
| connection that was least recently used, that connection is also least likely | the connection that was least recently used, that connection is also least | ||||||
| to be capable of re-use. Use CURLCLOSEPOLICY_OLDEST to make libcurl close the | likely to be capable of re-use. Use \fICURLCLOSEPOLICY_OLDEST\fP to make | ||||||
| oldest connection, the one that was created first among the ones in the | libcurl close the oldest connection, the one that was created first among the | ||||||
| connection cache. The other close policies are not support yet. (Added in 7.7) | ones in the connection cache. The other close policies are not support | ||||||
|  | yet. (Added in 7.7) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FRESH_CONNECT | .B CURLOPT_FRESH_CONNECT | ||||||
| Pass a long. Set to non-zero to make the next transfer use a new connection by | Pass a long. Set to non-zero to make the next transfer use a new (fresh) | ||||||
| force. If the connection cache is full before this connection, one of the | connection by force. If the connection cache is full before this connection, | ||||||
| existinf connections will be closed as according to the set policy. This | one of the existing connections will be closed as according to the selected or | ||||||
| option should be used with caution and only if you understand what it | default policy. This option should be used with caution and only if you | ||||||
| does. Set to 0 to have libcurl attempt re-use of an existing connection. | understand what it does. Set this to 0 to have libcurl attempt re-using an | ||||||
| (Added in 7.7) | existing connection (default behavior).  (Added in 7.7) | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_FORBID_REUSE | .B CURLOPT_FORBID_REUSE | ||||||
| Pass a long. Set to non-zero to make the next transfer explicitly close the | 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. | 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 | 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 | 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 | .TP | ||||||
| .B CURLOPT_RANDOM_FILE | .B CURLOPT_RANDOM_FILE | ||||||
| Pass a char * to a zero terminated file name. The file will be used to read | 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 | 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 | 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 | connection timeout (it will then only timeout on the system's internal | ||||||
| timeouts). See also the | timeouts). See also the \fICURLOPT_TIMEOUT\fP option. | ||||||
| .I CURLOPT_TIMEOUT |  | ||||||
| option. | \fBNOTE:\fP this does not work in unix multi-threaded programs, as it uses | ||||||
| .B NOTE | signals. | ||||||
| that this does not work in multi-threaded programs! |  | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_HTTPGET | .B CURLOPT_HTTPGET | ||||||
| Pass a long. If the long is non-zero, this forces the HTTP request to get back | 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 | .TP | ||||||
| .B CURLOPT_COOKIEJAR | .B CURLOPT_COOKIEJAR | ||||||
| Pass a file name as char *, zero terminated. This will make libcurl dump all | 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 | internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP | ||||||
| called. If no cookies are known, no file will be created. Specify "-" to | is called. If no cookies are known, no file will be created. Specify "-" to | ||||||
| instead have the cookies written to stdout. | instead have the cookies written to stdout. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_SSL_CIPHER_LIST | .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 | \'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you | ||||||
| compile OpenSSL. | compile OpenSSL. | ||||||
|  |  | ||||||
| You'll find all details about cipher lists on this URL: | You'll find more details about cipher lists on this URL: | ||||||
| .I http://www.openssl.org/docs/apps/ciphers.html | \fIhttp://www.openssl.org/docs/apps/ciphers.html\fP | ||||||
| .PP | .PP | ||||||
| .SH RETURN VALUE | .SH RETURN VALUE | ||||||
| 0 means the option was set properly, non-zero means an error as | CURLE_OK (zero) means that the option was set properly, non-zero means an | ||||||
| .I <curl/curl.h> | error occurred as \fI<curl/curl.h>\fP defines. | ||||||
| defines |  | ||||||
| .SH "SEE ALSO" | .SH "SEE ALSO" | ||||||
| .BR curl_easy_init "(3), " curl_easy_cleanup "(3), " | .BR curl_easy_init "(3), " curl_easy_cleanup "(3), " | ||||||
| .SH BUGS | .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] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $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 | .SH NAME | ||||||
| curl_formadd - add a section to a multipart/formdata HTTP POST | curl_formadd - add a section to a multipart/formdata HTTP POST | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| .B #include <curl/curl.h> | .B #include <curl/curl.h> | ||||||
| .sp | .sp | ||||||
| .BI "CURLcode curl_formadd(struct HttpPost ** " firstitem, | .BI "int curl_formadd(struct HttpPost ** " firstitem, | ||||||
| .BI "struct HttpPost ** " lastitem, " ...);" | .BI "struct HttpPost ** " lastitem, " ...);" | ||||||
| .ad | .ad | ||||||
| .SH DESCRIPTION | .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 | 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. | the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP. | ||||||
| \fIlastitem\fP is set after each call and on repeated invokes it should be | \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 | left as set to allow repeated invokes to find the end of the list faster. | ||||||
| way. |  | ||||||
|  |  | ||||||
| After \fIlastitem\fP follow the real arguments that constitute the | After the \fIlastitem\fP pointer follow the real arguments. (If the following | ||||||
| new section (if the following description confuses you jump directly | description confuses you, jump directly to the examples): | ||||||
| to the examples): |  | ||||||
|  |  | ||||||
| CURLFORM_COPYNAME or CURLFORM_PTRNAME followed by a string is used for | \fBCURLFORM_COPYNAME\fP or \fBCURLFORM_PTRNAME\fP followed by a string is used | ||||||
| the name of the section. Optionally one may use CURLFORM_NAMELENGTH to | for the name of the section. Optionally one may use \fBCURLFORM_NAMELENGTH\fP | ||||||
| specify the length of the name (allowing null characters within the name). | 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, | The four options for providing values are: \fBCURLFORM_COPYCONTENTS\fP, | ||||||
| CURLFORM_PTRCONTENTS, or CURLFORM_FILE, followed by a char or void | \fBCURLFORM_PTRCONTENTS\fP, \fBCURLFORM_FILE\fP, or \fBCURLFORM_FILECONTENT\fP | ||||||
| pointer (allowed for PTRCONTENTS). | followed by a char or void pointer (allowed for PTRCONTENTS). | ||||||
|  |  | ||||||
| Other arguments may be CURLFORM_CONTENTTYPE if the | \fBCURLFORM_FILECONTENT\fP does a normal post like \fBCURLFORM_COPYCONTENTS\fP | ||||||
| user wishes to specify one (for FILE if no type is given the library | but the actual value is read from the filename given as a string. | ||||||
| tries to provide the correct one; for CONTENTS no Content-Type is sent |  | ||||||
| in this case) |  | ||||||
|  |  | ||||||
| For CURLFORM_PTRCONTENTS or CURLFORM_COPYNAME the user may also add | Other arguments may be \fBCURLFORM_CONTENTTYPE\fP if the user wishes to | ||||||
| CURLFORM_CONTENTSLENGTH followed by the length as a long (if not given | specify one (for FILE if no type is given the library tries to provide the | ||||||
| the library will use strlen to determine the length). | 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 | For \fBCURLFORM_PTRCONTENTS\fP or \fBCURLFORM_COPYNAME\fP the user may also | ||||||
| providing multiple CURLFORM_FILE arguments each followed by the filename | 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). | (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 | 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 | 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 | the function itself. You must call \fIcurl_formfree\fP after the form post has | ||||||
| been done to free the resources again. | been done to free the resources again. | ||||||
|  |  | ||||||
| This function will copy all input data except the data pointed to by | This function will copy all input data except the data pointed to by the | ||||||
| the arguments after CURLFORM_PTRNAME and CURLFORM_PTRCONTENTS and keep | arguments after \fBCURLFORM_PTRNAME\fP and \fBCURLFORM_PTRCONTENTS\fP and keep | ||||||
| its own version of it allocated until you call \fIcurl_formfree\fP. When | 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 | you've passed the pointer to \fIcurl_easy_setopt\fP, you must not free the | ||||||
| the list until after you've called \fIcurl_easy_cleanup\fP for the | list until after you've called \fIcurl_easy_cleanup\fP for the curl handle. If | ||||||
| curl handle. If you provide a pointer as an arguments after | you provide a pointer as an arguments after \fBCURLFORM_PTRNAME\fP or | ||||||
| CURLFORM_PTRNAME or CURLFORM_PTRCONTENTS you must ensure that the pointer | \fBCURLFORM_PTRCONTENTS\fP you must ensure that the pointer stays valid until | ||||||
| stays valid until you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP. | you call \fIcurl_form_free\fP and \fIcurl_easy_cleanup\fP. | ||||||
|  |  | ||||||
| See example below. | See example below. | ||||||
| .SH RETURN VALUE | .SH RETURN VALUE | ||||||
| @@ -74,6 +87,9 @@ Returns non-zero if an error occurs. | |||||||
|  char buffer[] = "test buffer"; |  char buffer[] = "test buffer"; | ||||||
|  char htmlbuffer[] = "<HTML>test buffer</HTML>"; |  char htmlbuffer[] = "<HTML>test buffer</HTML>"; | ||||||
|  long htmlbufferlength = strlen(htmlbuffer); |  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 |  /* add null character into htmlbuffer, to demonstrate that | ||||||
|     transfers of buffers containing null characters actually work |     transfers of buffers containing null characters actually work | ||||||
|  */ |  */ | ||||||
| @@ -82,40 +98,61 @@ Returns non-zero if an error occurs. | |||||||
|  /* Add simple name/content section */ |  /* Add simple name/content section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", | ||||||
|               CURLFORM_COPYCONTENTS, "content", CURLFORM_END);  |               CURLFORM_COPYCONTENTS, "content", CURLFORM_END);  | ||||||
|  |  | ||||||
|  /* Add simple name/content/contenttype section */ |  /* Add simple name/content/contenttype section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", | ||||||
|               CURLFORM_COPYCONTENTS, "<HTML></HTML>", |               CURLFORM_COPYCONTENTS, "<HTML></HTML>", | ||||||
|               CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); |               CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); | ||||||
|  |  | ||||||
|  /* Add name/ptrcontent section */ |  /* Add name/ptrcontent section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", | ||||||
|               CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); |               CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); | ||||||
|  |  | ||||||
|  /* Add ptrname/ptrcontent section */ |  /* Add ptrname/ptrcontent section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer, |  curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer, | ||||||
| 	      CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH, | 	      CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH, | ||||||
| 	      namelength, CURLFORM_END); | 	      namelength, CURLFORM_END); | ||||||
|  |  | ||||||
|  /* Add name/ptrcontent/contenttype section */ |  /* Add name/ptrcontent/contenttype section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole", | ||||||
|               CURLFORM_PTRCONTENTS, htmlbuffer, |               CURLFORM_PTRCONTENTS, htmlbuffer, | ||||||
|               CURLFORM_CONTENTSLENGTH, htmlbufferlength, |               CURLFORM_CONTENTSLENGTH, htmlbufferlength, | ||||||
|               CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); |               CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); | ||||||
|  |  | ||||||
|  /* Add simple file section */ |  /* Add simple file section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", | ||||||
|               CURLFORM_FILE, "my-face.jpg", CURLFORM_END); |               CURLFORM_FILE, "my-face.jpg", CURLFORM_END); | ||||||
|  |  | ||||||
|  /* Add file/contenttype section */ |  /* Add file/contenttype section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", | ||||||
|               CURLFORM_FILE, "my-face.jpg", |               CURLFORM_FILE, "my-face.jpg", | ||||||
|               CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); |               CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); | ||||||
|  |  | ||||||
|  /* Add two file section */ |  /* Add two file section */ | ||||||
|  curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", |  curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", | ||||||
|               CURLFORM_FILE, "my-face.jpg", |               CURLFORM_FILE, "my-face.jpg", | ||||||
|               CURLFORM_FILE, "your-face.jpg", CURLFORM_END); |               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 */ |  /* Set the form info */ | ||||||
|  curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); |  curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); | ||||||
|  |  | ||||||
| .SH "SEE ALSO" | .SH "SEE ALSO" | ||||||
| .BR curl_easy_setopt "(3), " | .BR curl_easy_setopt "(3), " | ||||||
| .BR curl_formparse "(3) [deprecated], " | .BR curl_formparse "(3) [deprecated], " | ||||||
| .BR curl_formfree "(3) | .BR curl_formfree "(3)" | ||||||
| .SH BUGS | .SH BUGS | ||||||
| Surely there are some, you tell me! | 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 \ | EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c postit2.c \ | ||||||
| 	     win32sockets.c persistant.c ftpget.c Makefile.example \ | 	     win32sockets.c persistant.c ftpget.c Makefile.example \ | ||||||
| 	     multithread.c getinmemory.c ftpupload.c | 	     multithread.c getinmemory.c ftpupload.c httpput.c | ||||||
|  |  | ||||||
| all: | all: | ||||||
| 	@echo "done" | 	@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 |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * 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_TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */ | ||||||
|   CURLE_OBSOLETE,	         /* 50 - removed after 7.7.3 */ |   CURLE_OBSOLETE,	         /* 50 - removed after 7.7.3 */ | ||||||
|   CURLE_SSL_PEER_CERTIFICATE,    /* 51 - peer's certificate wasn't ok */ |   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! */ |   CURL_LAST /* never use! */ | ||||||
| } CURLcode; | } CURLcode; | ||||||
| @@ -461,9 +462,25 @@ typedef enum { | |||||||
|   /* Specify which SSL ciphers to use */ |   /* Specify which SSL ciphers to use */ | ||||||
|   CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), |   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 */ |   CURLOPT_LASTENTRY /* the last unusued */ | ||||||
| } CURLoption; | } 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 { | typedef enum { | ||||||
|   TIMECOND_NONE, |   TIMECOND_NONE, | ||||||
|  |  | ||||||
| @@ -472,7 +489,7 @@ typedef enum { | |||||||
|   TIMECOND_LASTMOD, |   TIMECOND_LASTMOD, | ||||||
|  |  | ||||||
|   TIMECOND_LAST |   TIMECOND_LAST | ||||||
| } TimeCond; | } curl_TimeCond; | ||||||
|  |  | ||||||
| #ifdef __BEOS__ | #ifdef __BEOS__ | ||||||
| #include <support/SupportDefs.h> | #include <support/SupportDefs.h> | ||||||
| @@ -512,13 +529,23 @@ typedef enum { | |||||||
|   CFINIT(COPYCONTENTS), |   CFINIT(COPYCONTENTS), | ||||||
|   CFINIT(PTRCONTENTS), |   CFINIT(PTRCONTENTS), | ||||||
|   CFINIT(CONTENTSLENGTH), |   CFINIT(CONTENTSLENGTH), | ||||||
|  |   CFINIT(FILECONTENT), | ||||||
|  |   CFINIT(ARRAY), | ||||||
|  |   CFINIT(ARRAY_START), /* below are the options allowed within a array */ | ||||||
|   CFINIT(FILE), |   CFINIT(FILE), | ||||||
|   CFINIT(CONTENTTYPE), |   CFINIT(CONTENTTYPE), | ||||||
|   CFINIT(END), |   CFINIT(END), | ||||||
|  |   CFINIT(ARRAY_END),   /* up are the options allowed within a array */ | ||||||
|  |  | ||||||
|   CURLFORM_LASTENTRY /* the last unusued */ |   CURLFORM_LASTENTRY /* the last unusued */ | ||||||
| } CURLformoption; | } CURLformoption; | ||||||
|  |  | ||||||
|  | /* structure to be used as parameter for CURLFORM_ARRAY */ | ||||||
|  | struct curl_forms { | ||||||
|  | 	CURLformoption		option; | ||||||
|  | 	const char		*value; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* new external form function */ | /* new external form function */ | ||||||
| int curl_formadd(struct HttpPost **httppost, | int curl_formadd(struct HttpPost **httppost, | ||||||
|                  struct HttpPost **last_post, |                  struct HttpPost **last_post, | ||||||
| @@ -548,8 +575,8 @@ CURLcode curl_global_init(long flags); | |||||||
| void curl_global_cleanup(void); | void curl_global_cleanup(void); | ||||||
|  |  | ||||||
| /* This is the version number */ | /* This is the version number */ | ||||||
| #define LIBCURL_VERSION "7.8.2-pre1" | #define LIBCURL_VERSION "7.9.1" | ||||||
| #define LIBCURL_VERSION_NUM 0x070802 | #define LIBCURL_VERSION_NUM 0x070901 | ||||||
|  |  | ||||||
| /* linked-list structure for the CURLOPT_QUOTE option (and other) */ | /* linked-list structure for the CURLOPT_QUOTE option (and other) */ | ||||||
| struct curl_slist { | struct curl_slist { | ||||||
|   | |||||||
| @@ -46,6 +46,21 @@ void curl_easy_cleanup(CURL *curl); | |||||||
|  */ |  */ | ||||||
| CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); | 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 | #ifdef  __cplusplus | ||||||
| } | } | ||||||
| #endif | #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 | 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, | # 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 | # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to | ||||||
| # 1. | # 1. | ||||||
| @@ -59,7 +59,7 @@ escape.c       mprintf.c      telnet.c       \ | |||||||
| escape.h       getpass.c      netrc.c        telnet.h       \ | escape.h       getpass.c      netrc.c        telnet.h       \ | ||||||
| getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \ | 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 \ | 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 | noinst_HEADERS = setup.h transfer.h | ||||||
|  |  | ||||||
|   | |||||||
| @@ -58,7 +58,8 @@ SOURCES	   = \ | |||||||
| 	version.c \ | 	version.c \ | ||||||
| 	easy.c \ | 	easy.c \ | ||||||
| 	strequal.c \ | 	strequal.c \ | ||||||
| 	strtok.c | 	strtok.c \ | ||||||
|  | 	connect.c | ||||||
|  |  | ||||||
| OBJECTS = $(SOURCES:.c=.obj) | OBJECTS = $(SOURCES:.c=.obj) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| ############################################################# | ############################################################# | ||||||
| # $Id$ |  | ||||||
| # | # | ||||||
| ## Makefile for building libcurl.a with MingW32 (GCC-2.95) and | ## Makefile for building libcurl.a with MingW32 (GCC-2.95) and | ||||||
| ## optionally OpenSSL (0.9.6) | ## optionally OpenSSL (0.9.6) | ||||||
| @@ -12,7 +11,7 @@ CC = gcc | |||||||
| AR = ar | AR = ar | ||||||
| RANLIB = ranlib | RANLIB = ranlib | ||||||
| STRIP = strip -g | STRIP = strip -g | ||||||
| OPENSSL_PATH = ../../openssl-0.9.6 | OPENSSL_PATH = ../../openssl-0.9.6b | ||||||
|  |  | ||||||
| ######################################################## | ######################################################## | ||||||
| ## Nothing more to do below this line! | ## 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	\ | 	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		\ | 	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 \ | 	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 \ | libcurl_a_OBJECTS =  file.o timeval.o base64.o hostip.o progress.o \ | ||||||
| 	formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \ | 	formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \ | ||||||
| 	speedcheck.o getdate.o transfer.o ldap.o ssluse.o version.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 \ | 	getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \ | ||||||
| 	strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \ | 	strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o \ | ||||||
| 	strtok.o | 	strtok.o connect.o | ||||||
|  |  | ||||||
| LIBRARIES =  $(libcurl_a_LIBRARIES) | LIBRARIES =  $(libcurl_a_LIBRARIES) | ||||||
| SOURCES = $(libcurl_a_SOURCES) | 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 | libcurl.dll libcurldll.a: libcurl.a libcurl.def dllinit.o | ||||||
| 	-@erase $@ | 	-@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) $@ | 	$(STRIP) $@ | ||||||
|  |  | ||||||
| # remove the last line above to keep debug info | # 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" | CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS" | ||||||
| LFLAGS = /nologo | LFLAGS = /nologo | ||||||
| LINKLIBS = wsock32.lib | LINKLIBS = ws2_32.lib | ||||||
| LINKSLIBS = libeay32.lib ssleay32.lib RSAglue.lib | LINKSLIBS = libeay32.lib ssleay32.lib RSAglue.lib | ||||||
|  |  | ||||||
| RELEASE_OBJS= \ | RELEASE_OBJS= \ | ||||||
| @@ -62,7 +62,8 @@ RELEASE_OBJS= \ | |||||||
| 	versionr.obj \ | 	versionr.obj \ | ||||||
| 	easyr.obj \ | 	easyr.obj \ | ||||||
| 	strequalr.obj \ | 	strequalr.obj \ | ||||||
| 	strtokr.obj | 	strtokr.obj \ | ||||||
|  | 	connectr.obj | ||||||
|  |  | ||||||
| DEBUG_OBJS= \ | DEBUG_OBJS= \ | ||||||
| 	base64d.obj \ | 	base64d.obj \ | ||||||
| @@ -94,7 +95,8 @@ DEBUG_OBJS= \ | |||||||
| 	versiond.obj  \ | 	versiond.obj  \ | ||||||
| 	easyd.obj \ | 	easyd.obj \ | ||||||
| 	strequald.obj \ | 	strequald.obj \ | ||||||
| 	strtokd.obj | 	strtokd.obj \ | ||||||
|  | 	connectd.obj | ||||||
|  |  | ||||||
| RELEASE_SSL_OBJS= \ | RELEASE_SSL_OBJS= \ | ||||||
| 	base64rs.obj \ | 	base64rs.obj \ | ||||||
| @@ -126,7 +128,8 @@ RELEASE_SSL_OBJS= \ | |||||||
| 	versionrs.obj \ | 	versionrs.obj \ | ||||||
| 	easyrs.obj \ | 	easyrs.obj \ | ||||||
| 	strequalrs.obj \ | 	strequalrs.obj \ | ||||||
| 	strtokrs.obj | 	strtokrs.obj \ | ||||||
|  | 	connectrs.obj | ||||||
|  |  | ||||||
| LINK_OBJS= \ | LINK_OBJS= \ | ||||||
| 	base64.obj \ | 	base64.obj \ | ||||||
| @@ -158,7 +161,8 @@ LINK_OBJS= \ | |||||||
| 	version.obj \ | 	version.obj \ | ||||||
| 	easy.obj \ | 	easy.obj \ | ||||||
| 	strequal.obj \ | 	strequal.obj \ | ||||||
| 	strtok.obj | 	strtok.obj \ | ||||||
|  | 	connect.obj | ||||||
|  |  | ||||||
| all : release | all : release | ||||||
|  |  | ||||||
| @@ -232,6 +236,8 @@ strequalr.obj: strequal.c | |||||||
| 	$(CCR) $(CFLAGS) strequal.c | 	$(CCR) $(CFLAGS) strequal.c | ||||||
| strtokr.obj:strtok.c | strtokr.obj:strtok.c | ||||||
| 	$(CCR) $(CFLAGS) strtok.c | 	$(CCR) $(CFLAGS) strtok.c | ||||||
|  | connectr.obj:connect.c | ||||||
|  | 	$(CCR) $(CFLAGS) connect.c | ||||||
|  |  | ||||||
| ## Debug | ## Debug | ||||||
| base64d.obj: base64.c | base64d.obj: base64.c | ||||||
| @@ -294,6 +300,8 @@ strequald.obj: strequal.c | |||||||
| 	$(CCD) $(CFLAGS) strequal.c | 	$(CCD) $(CFLAGS) strequal.c | ||||||
| strtokd.obj:strtok.c | strtokd.obj:strtok.c | ||||||
| 	$(CCD) $(CFLAGS) strtok.c | 	$(CCD) $(CFLAGS) strtok.c | ||||||
|  | connectd.obj:connect.c | ||||||
|  | 	$(CCR) $(CFLAGS) connect.c | ||||||
|  |  | ||||||
| ## Release SSL | ## Release SSL | ||||||
| base64rs.obj: base64.c | base64rs.obj: base64.c | ||||||
| @@ -356,7 +364,8 @@ strequalrs.obj: strequal.c | |||||||
| 	$(CCRS) $(CFLAGS) strequal.c | 	$(CCRS) $(CFLAGS) strequal.c | ||||||
| strtokrs.obj:strtok.c | strtokrs.obj:strtok.c | ||||||
| 	$(CCRS) $(CFLAGS) strtok.c | 	$(CCRS) $(CFLAGS) strtok.c | ||||||
|  | connectrs.obj:connect.c | ||||||
|  | 	$(CCR) $(CFLAGS) connect.c | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
| 	-@erase *.obj | 	-@erase *.obj | ||||||
|   | |||||||
| @@ -265,6 +265,6 @@ void *suck(int *lenptr) { | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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 * | struct Cookie * | ||||||
| Curl_cookie_add(struct CookieInfo *c, | Curl_cookie_add(struct CookieInfo *c, | ||||||
|                 bool httpheader, /* TRUE if HTTP header-style line */ |                 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; |   struct Cookie *clist; | ||||||
|   char what[MAX_COOKIE_LINE]; |   char what[MAX_COOKIE_LINE]; | ||||||
| @@ -194,6 +195,10 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|         ptr++; |         ptr++; | ||||||
|       semiptr=strchr(ptr, ';'); /* now, find the next semicolon */ |       semiptr=strchr(ptr, ';'); /* now, find the next semicolon */ | ||||||
|     } while(semiptr); |     } while(semiptr); | ||||||
|  |  | ||||||
|  |     if(NULL == co->domain) | ||||||
|  |       /* no domain given in the header line, set the default now */ | ||||||
|  |       co->domain=domain?strdup(domain):NULL; | ||||||
|   } |   } | ||||||
|   else { |   else { | ||||||
|     /* This line is NOT a HTTP header style line, we do offer support for |     /* 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); |           free(clist->maxage); | ||||||
|  |  | ||||||
|         *clist = *co;  /* then store all the new data */ |         *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 */ |   c->running = FALSE; /* this is not running, this is init */ | ||||||
|  |  | ||||||
|   if(strequal(file, "-")) { |   if(file && strequal(file, "-")) { | ||||||
|     fp = stdin; |     fp = stdin; | ||||||
|     fromfile=FALSE; |     fromfile=FALSE; | ||||||
|   } |   } | ||||||
| @@ -441,7 +449,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) | |||||||
|       while(*lineptr && isspace((int)*lineptr)) |       while(*lineptr && isspace((int)*lineptr)) | ||||||
|         lineptr++; |         lineptr++; | ||||||
|  |  | ||||||
|       Curl_cookie_add(c, headerline, lineptr); |       Curl_cookie_add(c, headerline, lineptr, NULL); | ||||||
|     } |     } | ||||||
|     if(fromfile) |     if(fromfile) | ||||||
|       fclose(fp); |       fclose(fp); | ||||||
| @@ -619,7 +627,7 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere) | |||||||
|   if(c) { |   if(c) { | ||||||
|     fputs("# Netscape HTTP Cookie File\n" |     fputs("# Netscape HTTP Cookie File\n" | ||||||
|           "# http://www.netscape.com/newsref/std/cookie_spec.html\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); |           out); | ||||||
|     co = c->cookies; |     co = c->cookies; | ||||||
|       |       | ||||||
| @@ -632,13 +640,13 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere) | |||||||
|               "%u\t" /* expires */ |               "%u\t" /* expires */ | ||||||
|               "%s\t" /* name */ |               "%s\t" /* name */ | ||||||
|               "%s\n", /* value */ |               "%s\n", /* value */ | ||||||
|               co->domain, |               co->domain?co->domain:"unknown", | ||||||
|               co->field1==2?"TRUE":"FALSE", |               co->field1==2?"TRUE":"FALSE", | ||||||
|               co->path, |               co->path?co->path:"/", | ||||||
|               co->secure?"TRUE":"FALSE", |               co->secure?"TRUE":"FALSE", | ||||||
|               (unsigned int)co->expires, |               (unsigned int)co->expires, | ||||||
|               co->name, |               co->name, | ||||||
|               co->value); |               co->value?co->value:""); | ||||||
|  |  | ||||||
|       co=co->next; |       co=co->next; | ||||||
|     } |     } | ||||||
| @@ -681,6 +689,6 @@ int main(int argc, char **argv) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -68,7 +68,13 @@ struct CookieInfo { | |||||||
| #define MAX_NAME 256 | #define MAX_NAME 256 | ||||||
| #define MAX_NAME_TXT "255" | #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 CookieInfo *Curl_cookie_init(char *, struct CookieInfo *); | ||||||
| struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); | struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); | ||||||
| void Curl_cookie_freelist(struct Cookie *); | void Curl_cookie_freelist(struct Cookie *); | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ BSC32=bscmake.exe | |||||||
| # ADD BSC32 /nologo | # ADD BSC32 /nologo | ||||||
| LINK32=link.exe | 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 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" | !ELSEIF  "$(CFG)" == "curllib - Win32 Debug" | ||||||
|  |  | ||||||
| @@ -81,7 +81,7 @@ BSC32=bscmake.exe | |||||||
| # ADD BSC32 /nologo | # ADD BSC32 /nologo | ||||||
| LINK32=link.exe | 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 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 | # SUBTRACT LINK32 /nodefaultlib | ||||||
|  |  | ||||||
| !ENDIF  | !ENDIF  | ||||||
| @@ -99,6 +99,10 @@ SOURCE=.\base64.c | |||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=.\connect.c | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
| SOURCE=.\cookie.c | SOURCE=.\cookie.c | ||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
| @@ -247,6 +251,10 @@ SOURCE=.\base64.h | |||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=.\connect.h | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
| SOURCE=.\cookie.h | SOURCE=.\cookie.h | ||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|   | |||||||
							
								
								
									
										81
									
								
								lib/dict.c
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								lib/dict.c
									
									
									
									
									
								
							| @@ -136,25 +136,25 @@ CURLcode Curl_dict(struct connectdata *conn) | |||||||
|       nth = atoi(nthdef); |       nth = atoi(nthdef); | ||||||
|     } |     } | ||||||
|        |        | ||||||
|     Curl_sendf(conn->firstsocket, conn, |     result = Curl_sendf(conn->firstsocket, conn, | ||||||
|                "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" |                         "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||||
|                "MATCH " |                         "MATCH " | ||||||
|                "%s "    /* database */ |                         "%s "    /* database */ | ||||||
|                "%s "    /* strategy */ |                         "%s "    /* strategy */ | ||||||
|                "%s\n"   /* word */ |                         "%s\n"   /* word */ | ||||||
|                "QUIT\n", |                         "QUIT\n", | ||||||
| 	     |  | ||||||
|                database, |  | ||||||
|                strategy, |  | ||||||
|                word |  | ||||||
|                ); |  | ||||||
|      |  | ||||||
|     result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, |  | ||||||
|                            -1, NULL); /* no upload */ |  | ||||||
|                          |                          | ||||||
|  |                         database, | ||||||
|  |                         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) |     if(result) | ||||||
|       return result; |       return result; | ||||||
|      |  | ||||||
|   } |   } | ||||||
|   else if (strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || |   else if (strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || | ||||||
|            strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || |            strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || | ||||||
| @@ -186,19 +186,19 @@ CURLcode Curl_dict(struct connectdata *conn) | |||||||
|       nth = atoi(nthdef); |       nth = atoi(nthdef); | ||||||
|     } |     } | ||||||
|        |        | ||||||
|     Curl_sendf(conn->firstsocket, conn, |     result = Curl_sendf(conn->firstsocket, conn, | ||||||
|                "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" |                         "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||||
|                "DEFINE " |                         "DEFINE " | ||||||
|                "%s "     /* database */ |                         "%s "     /* database */ | ||||||
|                "%s\n"    /* word */ |                         "%s\n"    /* word */ | ||||||
|                "QUIT\n", |                         "QUIT\n", | ||||||
|                 |                         database, | ||||||
|                database, |                         word); | ||||||
|                word |     if(result) | ||||||
|                ); |       failf(data, "Failed sending DICT request"); | ||||||
|      |     else | ||||||
|     result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, |       result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||||
|                            -1, NULL); /* no upload */ |                              -1, NULL); /* no upload */ | ||||||
|      |      | ||||||
|     if(result) |     if(result) | ||||||
|       return result; |       return result; | ||||||
| @@ -215,18 +215,17 @@ CURLcode Curl_dict(struct connectdata *conn) | |||||||
|         if (ppath[i] == ':') |         if (ppath[i] == ':') | ||||||
|           ppath[i] = ' '; |           ppath[i] = ' '; | ||||||
|       } |       } | ||||||
|       Curl_sendf(conn->firstsocket, conn, |       result = Curl_sendf(conn->firstsocket, conn, | ||||||
|                  "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" |                           "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||||
|                  "%s\n" |                           "%s\n" | ||||||
|                  "QUIT\n", |                           "QUIT\n", ppath); | ||||||
|                  ppath); |       if(result) | ||||||
|        |         failf(data, "Failed sending DICT request"); | ||||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, |       else | ||||||
|                              -1, NULL); |         result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||||
|        |                                -1, NULL); | ||||||
|       if(result) |       if(result) | ||||||
|         return result; |         return result; | ||||||
|        |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -237,6 +236,6 @@ CURLcode Curl_dict(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -87,6 +87,6 @@ DllMain ( | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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;   |   WORD wVersionRequested;   | ||||||
|   WSADATA wsaData;  |   WSADATA wsaData;  | ||||||
|   int err;  |   int err;  | ||||||
|   wVersionRequested = MAKEWORD(1, 1);  |   wVersionRequested = MAKEWORD(2, 0);  | ||||||
|      |      | ||||||
|   err = WSAStartup(wVersionRequested, &wsaData);  |   err = WSAStartup(wVersionRequested, &wsaData);  | ||||||
|      |      | ||||||
| @@ -103,14 +103,14 @@ static CURLcode win32_init(void) | |||||||
|     /* winsock.dll.     */  |     /* winsock.dll.     */  | ||||||
|     return CURLE_FAILED_INIT;  |     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 */  |   /* Note that if the DLL supports versions greater */  | ||||||
|   /* than 1.1 in addition to 1.1, it will still return */  |   /* than 2.0 in addition to 2.0, it will still return */  | ||||||
|   /* 1.1 in wVersion since that is the version we */  |   /* 2.0 in wVersion since that is the version we */  | ||||||
|   /* requested. */  |   /* requested. */  | ||||||
|      |      | ||||||
|   if ( LOBYTE( wsaData.wVersion ) != 1 ||  |   if ( LOBYTE( wsaData.wVersion ) != 2 ||  | ||||||
|        HIBYTE( wsaData.wVersion ) != 1 ) {  |        HIBYTE( wsaData.wVersion ) != 0 ) {  | ||||||
|     /* Tell the user that we couldn't find a useable */  |     /* Tell the user that we couldn't find a useable */  | ||||||
|  |  | ||||||
|     /* winsock.dll. */  |     /* winsock.dll. */  | ||||||
| @@ -293,6 +293,12 @@ CURL *curl_easy_duphandle(CURL *incurl) | |||||||
|   outcurl->progress.flags    = data->progress.flags; |   outcurl->progress.flags    = data->progress.flags; | ||||||
|   outcurl->progress.callback = data->progress.callback; |   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' */ |   /* duplicate all values in 'change' */ | ||||||
|   if(data->change.url) { |   if(data->change.url) { | ||||||
|     outcurl->change.url = strdup(data->change.url); |     outcurl->change.url = strdup(data->change.url); | ||||||
| @@ -314,6 +320,6 @@ CURL *curl_easy_duphandle(CURL *incurl) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -115,6 +115,6 @@ char *curl_unescape(const char *string, int length) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -201,6 +201,6 @@ CURLcode Curl_file(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
							
								
								
									
										483
									
								
								lib/formdata.c
									
									
									
									
									
								
							
							
						
						
									
										483
									
								
								lib/formdata.c
									
									
									
									
									
								
							| @@ -80,6 +80,23 @@ Content-Disposition: attachment; filename="inet_ntoa_r.h" | |||||||
| Content-Type: text/plain | 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: |   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 |   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) { |   if(post) { | ||||||
|     memset(post, 0, sizeof(struct HttpPost)); |     memset(post, 0, sizeof(struct HttpPost)); | ||||||
|     post->name = name; |     post->name = name; | ||||||
|     post->namelength = namelength; |     post->namelength = name?(namelength?namelength:(long)strlen(name)):0; | ||||||
|     post->contents = value; |     post->contents = value; | ||||||
|     post->contentslength = contentslength; |     post->contentslength = contentslength; | ||||||
|     post->contenttype = contenttype; |     post->contenttype = contenttype; | ||||||
| @@ -432,9 +449,9 @@ static struct HttpPost * AddHttpPost (char * name, | |||||||
|  * parent_form_info is NULL. |  * parent_form_info is NULL. | ||||||
|  * |  * | ||||||
|  ***************************************************************************/ |  ***************************************************************************/ | ||||||
| static FormInfo * AddFormInfo (char *value, | static FormInfo * AddFormInfo(char *value, | ||||||
| 			       char *contenttype, |                               char *contenttype, | ||||||
| 			       FormInfo *parent_form_info) |                               FormInfo *parent_form_info) | ||||||
| { | { | ||||||
|   FormInfo *form_info; |   FormInfo *form_info; | ||||||
|   form_info = (FormInfo *)malloc(sizeof(FormInfo)); |   form_info = (FormInfo *)malloc(sizeof(FormInfo)); | ||||||
| @@ -472,7 +489,7 @@ static FormInfo * AddFormInfo (char *value, | |||||||
|  * Returns some valid contenttype for filename. |  * Returns some valid contenttype for filename. | ||||||
|  * |  * | ||||||
|  ***************************************************************************/ |  ***************************************************************************/ | ||||||
| static const char * ContentTypeForFilename (char *filename, | static const char * ContentTypeForFilename (const char *filename, | ||||||
| 					    const char *prevtype) | 					    const char *prevtype) | ||||||
| { | { | ||||||
|   const char *contenttype = NULL; |   const char *contenttype = NULL; | ||||||
| @@ -528,16 +545,21 @@ static const char * ContentTypeForFilename (char *filename, | |||||||
|  ***************************************************************************/ |  ***************************************************************************/ | ||||||
| static int AllocAndCopy (char **buffer, int buffer_length) | static int AllocAndCopy (char **buffer, int buffer_length) | ||||||
| { | { | ||||||
|   char *src = *buffer; |   const char *src = *buffer; | ||||||
|   int length; |   int length, add = 0; | ||||||
|   if (buffer_length) |   if (buffer_length) | ||||||
|     length = buffer_length; |     length = buffer_length; | ||||||
|   else |   else { | ||||||
|     length = strlen(*buffer); |     length = strlen(*buffer); | ||||||
|   *buffer = (char*)malloc(length); |     add = 1; | ||||||
|  |   } | ||||||
|  |   *buffer = (char*)malloc(length+add); | ||||||
|   if (!*buffer) |   if (!*buffer) | ||||||
|     return 1; |     return 1; | ||||||
|   memcpy(*buffer, src, length); |   memcpy(*buffer, src, length); | ||||||
|  |   /* if length unknown do null termination */ | ||||||
|  |   if (add) | ||||||
|  |     (*buffer)[length] = '\0'; | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -561,11 +583,11 @@ static int AllocAndCopy (char **buffer, int buffer_length) | |||||||
|  * |  * | ||||||
|  * Simple name/value pair with copied contents: |  * Simple name/value pair with copied contents: | ||||||
|  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", |  * 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: |  * name/value pair where only the content pointer is remembered: | ||||||
|  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", |  * 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) |  * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) | ||||||
|  * |  * | ||||||
|  * storing a filename (CONTENTTYPE is optional!): |  * 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", |  * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", | ||||||
|  * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); |  * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); | ||||||
|  * |  * | ||||||
|  * Returns 0 on success, 1 if the FormInfo allocation fails, 2 if one |  * Returns: | ||||||
|  * option is given twice for one Form, 3 if a null pointer was given for |  * FORMADD_OK             on success | ||||||
|  * a char *, 4 if the allocation of a FormInfo struct failed, 5 if an |  * FORMADD_MEMORY         if the FormInfo allocation fails | ||||||
|  * unknown option was used, 6 if the some FormInfo is not complete (or |  * FORMADD_OPTION_TWICE   if one option is given twice for one Form | ||||||
|  * has an error), 7 if a HttpPost struct cannot be allocated, and 8 |  * FORMADD_NULL           if a null pointer was given for a char | ||||||
|  * if some allocation for string copying failed. |  * 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 | static | ||||||
| int FormAdd(struct HttpPost **httppost, | FORMcode FormAdd(struct HttpPost **httppost, | ||||||
|             struct HttpPost **last_post, |                  struct HttpPost **last_post, | ||||||
|             va_list params) |                  va_list params) | ||||||
| { | { | ||||||
|   FormInfo *first_form_info, *current_form_info, *form_info; |   FormInfo *first_form, *current_form, *form; | ||||||
|   int return_value = 0; |   FORMcode return_value = FORMADD_OK; | ||||||
|   const char *prevtype = NULL; |   const char *prevtype = NULL; | ||||||
|   struct HttpPost *post = 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)); |   /* This is a state variable, that if TRUE means that we're parsing an | ||||||
|   if(first_form_info) { |      array that we got passed to us. If FALSE we're parsing the input | ||||||
|     memset(first_form_info, 0, sizeof(FormInfo)); |      va_list arguments. */ | ||||||
|     current_form_info = first_form_info; |   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 |   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) && |   while (1) { | ||||||
|           (return_value == 0) ) |  | ||||||
|   { |     /* break if we have an error to report */ | ||||||
|     switch (next_option) |     if (return_value != FORMADD_OK) | ||||||
|     { |       break; | ||||||
|       case CURLFORM_PTRNAME: |  | ||||||
|         current_form_info->flags |= HTTPPOST_PTRNAME; /* fall through */ |     /* first see if we have more parts of the array param */ | ||||||
|       case CURLFORM_COPYNAME: |     if ( array_state ) { | ||||||
|         if (current_form_info->name) |       /* get the upcoming option from the given array */ | ||||||
|           return_value = 2; |       option = forms->option; | ||||||
|         else { |       array_value = forms->value; | ||||||
|           if (next_option == CURLFORM_PTRNAME) |  | ||||||
|             current_form_info->name = va_arg(params, char *); |       forms++; /* advance this to next entry */ | ||||||
|           else { |       if (CURLFORM_END == option) { | ||||||
| 	    char *name = va_arg(params, char *); |         /* end of array state */ | ||||||
| 	    if (name) |         array_state = FALSE; | ||||||
| 	      current_form_info->name = name; /* store for the moment */ |         continue; | ||||||
| 	    else |       } | ||||||
| 	      return_value = 3; |       else { | ||||||
| 	  } |         /* 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; |         break; | ||||||
|       case CURLFORM_NAMELENGTH: |     } | ||||||
|         if (current_form_info->namelength) |  | ||||||
|           return_value = 2; |     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->name = name; /* store for the moment */ | ||||||
|         else |         else | ||||||
|           current_form_info->namelength = va_arg(params, long); |           return_value = FORMADD_NULL; | ||||||
|         break; |       } | ||||||
|       case CURLFORM_PTRCONTENTS: |       break; | ||||||
|         current_form_info->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ |     case CURLFORM_NAMELENGTH: | ||||||
|       case CURLFORM_COPYCONTENTS: |       if (current_form->namelength) | ||||||
|         if (current_form_info->value) |         return_value = FORMADD_OPTION_TWICE; | ||||||
|           return_value = 2; |       else | ||||||
|         else { |         current_form->namelength = va_arg(params, long); | ||||||
|           if (next_option == CURLFORM_PTRCONTENTS) |       break; | ||||||
|             current_form_info->value = va_arg(params, char *); |  | ||||||
|           else { |       /* | ||||||
| 	    char *value = va_arg(params, char *); |        * Set the contents property. | ||||||
| 	    if (value) |        */ | ||||||
| 	      current_form_info->value = value; /* store for the moment */ |     case CURLFORM_PTRCONTENTS: | ||||||
| 	    else |       current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ | ||||||
| 	      return_value = 3; |     case CURLFORM_COPYCONTENTS: | ||||||
| 	  } |       if (current_form->value) | ||||||
|  |         return_value = FORMADD_OPTION_TWICE; | ||||||
|  |       else { | ||||||
|  |         char *value = va_arg(params, char *); | ||||||
|  |         if (value) | ||||||
|  |           current_form->value = value; /* store for the moment */ | ||||||
|  |         else | ||||||
|  |           return_value = FORMADD_NULL; | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     case CURLFORM_CONTENTSLENGTH: | ||||||
|  |       if (current_form->contentslength) | ||||||
|  |         return_value = FORMADD_OPTION_TWICE; | ||||||
|  |       else | ||||||
|  |         current_form->contentslength = va_arg(params, long); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |       /* 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 (filename) { | ||||||
|  |           current_form->value = strdup(filename); | ||||||
|  |           current_form->flags |= HTTPPOST_READFILE; | ||||||
|         } |         } | ||||||
|         break; |  | ||||||
|       case CURLFORM_CONTENTSLENGTH: |  | ||||||
|         if (current_form_info->contentslength) |  | ||||||
|           return_value = 2; |  | ||||||
|         else |         else | ||||||
|           current_form_info->contentslength = va_arg(params, long); |           return_value = FORMADD_NULL; | ||||||
|         break; |       } | ||||||
|       case CURLFORM_FILE: { |       break; | ||||||
| 	char *filename = va_arg(params, char *); |  | ||||||
| 	if (current_form_info->value) { |       /* We upload a file */ | ||||||
|           if (current_form_info->flags & HTTPPOST_FILENAME) { |     case CURLFORM_FILE: | ||||||
| 	    if (filename) { |       { | ||||||
| 	      if (!(current_form_info = AddFormInfo (strdup(filename), |         const char *filename = NULL; | ||||||
| 						     NULL, current_form_info))) |         if (array_state) | ||||||
| 		return_value = 4; |           filename = array_value; | ||||||
| 	    } |         else | ||||||
| 	    else |           filename = va_arg(params, const char *); | ||||||
| 	      return_value = 3; |         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 = FORMADD_NULL; | ||||||
|           } |           } | ||||||
|           else |           else | ||||||
|             return_value = 2; |             return_value = FORMADD_OPTION_TWICE; | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
| 	  if (filename) |           if (filename) | ||||||
| 	    current_form_info->value = strdup(filename); |             current_form->value = strdup(filename); | ||||||
| 	  else |           else | ||||||
| 	    return_value = 3; |             return_value = FORMADD_NULL; | ||||||
|           current_form_info->flags |= HTTPPOST_FILENAME; |           current_form->flags |= HTTPPOST_FILENAME; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case CURLFORM_CONTENTTYPE: { |     case CURLFORM_CONTENTTYPE: | ||||||
| 	char *contenttype = va_arg(params, char *); |       { | ||||||
|         if (current_form_info->contenttype) { | 	const char *contenttype = NULL; | ||||||
|           if (current_form_info->flags & HTTPPOST_FILENAME) { |         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 (contenttype) { | ||||||
|               if (!(current_form_info = AddFormInfo (NULL, |               if (!(current_form = AddFormInfo(NULL, | ||||||
|                                                      strdup(contenttype), |                                                strdup(contenttype), | ||||||
|                                                      current_form_info))) |                                                current_form))) | ||||||
|                 return_value = 4; |                 return_value = FORMADD_MEMORY; | ||||||
|             } |             } | ||||||
| 	    else | 	    else | ||||||
| 	      return_value = 3; | 	      return_value = FORMADD_NULL; | ||||||
|           } |           } | ||||||
|           else |           else | ||||||
|             return_value = 2; |             return_value = FORMADD_OPTION_TWICE; | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
| 	  if (contenttype) | 	  if (contenttype) | ||||||
| 	    current_form_info->contenttype = strdup(contenttype); | 	    current_form->contenttype = strdup(contenttype); | ||||||
| 	  else | 	  else | ||||||
| 	    return_value = 3; | 	    return_value = FORMADD_NULL; | ||||||
| 	} | 	} | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       default: |     default: | ||||||
|         fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", next_option); |       fprintf (stderr, "got unknown CURLFORM_OPTION: %d\n", option); | ||||||
|         return_value = 5; |       return_value = FORMADD_UNKNOWN_OPTION; | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   /* 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) ) |  | ||||||
|          ) { |  | ||||||
|       return_value = 6; |  | ||||||
|       break; |  | ||||||
|     } |     } | ||||||
|     else { |   } | ||||||
|       if ( (form_info->flags & HTTPPOST_FILENAME) && |  | ||||||
| 	   (!form_info->contenttype) ) { |   if(FORMADD_OK == return_value) { | ||||||
| 	/* our contenttype is missing */ |     /* go through the list, check for copleteness and if everything is | ||||||
| 	form_info->contenttype |      * alright add the HttpPost item otherwise set return_value accordingly */ | ||||||
| 	  = strdup(ContentTypeForFilename(form_info->value, prevtype)); |      | ||||||
|  |     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 = FORMADD_INCOMPLETE; | ||||||
|  |         break; | ||||||
|       } |       } | ||||||
|       if ( !(form_info->flags & HTTPPOST_PTRNAME) && |       else { | ||||||
| 	   (form_info == first_form_info) ) { |         if ( (form->flags & HTTPPOST_FILENAME) && | ||||||
| 	/* copy name (without strdup; possibly contains null characters) */ |              !form->contenttype ) { | ||||||
| 	if (AllocAndCopy(&form_info->name, form_info->namelength)) { |           /* our contenttype is missing */ | ||||||
| 	  return_value = 8; |           form->contenttype | ||||||
| 	  break; |             = strdup(ContentTypeForFilename(form->value, prevtype)); | ||||||
| 	} |         } | ||||||
|  |         if ( !(form->flags & HTTPPOST_PTRNAME) && | ||||||
|  |              (form == first_form) ) { | ||||||
|  |           /* copy name (without strdup; possibly contains null characters) */ | ||||||
|  |           if (AllocAndCopy(&form->name, form->namelength)) { | ||||||
|  |             return_value = FORMADD_MEMORY; | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if ( !(form->flags & HTTPPOST_FILENAME) && | ||||||
|  |              !(form->flags & HTTPPOST_READFILE) &&  | ||||||
|  |              !(form->flags & HTTPPOST_PTRCONTENTS) ) { | ||||||
|  |           /* copy value (without strdup; possibly contains null characters) */ | ||||||
|  |           if (AllocAndCopy(&form->value, form->contentslength)) { | ||||||
|  |             return_value = FORMADD_MEMORY; | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if ( (post = AddHttpPost(form->name, form->namelength, | ||||||
|  |                                  form->value, form->contentslength, | ||||||
|  |                                  form->contenttype, form->flags, | ||||||
|  |                                  post, httppost, | ||||||
|  |                                  last_post)) == NULL) { | ||||||
|  |           return_value = FORMADD_MEMORY; | ||||||
|  |         } | ||||||
|  |         if (form->contenttype) | ||||||
|  |           prevtype = form->contenttype; | ||||||
|       } |       } | ||||||
|       if ( !(form_info->flags & HTTPPOST_FILENAME) && |  | ||||||
| 	   !(form_info->flags & HTTPPOST_PTRCONTENTS) ) { |  | ||||||
| 	/* copy value (without strdup; possibly contains null characters) */ |  | ||||||
| 	if (AllocAndCopy(&form_info->value, form_info->contentslength)) { |  | ||||||
| 	  return_value = 8; |  | ||||||
| 	  break; |  | ||||||
| 	} |  | ||||||
|       } |  | ||||||
|       if ( (post = AddHttpPost (form_info->name, form_info->namelength, |  | ||||||
|                                 form_info->value, form_info->contentslength, |  | ||||||
|                                 form_info->contenttype, form_info->flags, |  | ||||||
| 				post, httppost, |  | ||||||
|                                 last_post)) == NULL) { |  | ||||||
|         return_value = 7; |  | ||||||
|       } |  | ||||||
|       if (form_info->contenttype) |  | ||||||
| 	prevtype = form_info->contenttype; |  | ||||||
|     } |     } | ||||||
|     form_info = form_info->more; |   } | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   /* and finally delete the allocated memory */ |   /* always delete the allocated memory before returning */ | ||||||
|   form_info = first_form_info; |   form = first_form; | ||||||
|   while (form_info != NULL) { |   while (form != NULL) { | ||||||
|     FormInfo *delete_form_info; |     FormInfo *delete_form; | ||||||
|      |      | ||||||
|     delete_form_info = form_info; |     delete_form = form; | ||||||
|     form_info = form_info->more; |     form = form->more; | ||||||
|     free (delete_form_info); |     free (delete_form); | ||||||
|   }; |   } | ||||||
|  |  | ||||||
|   return return_value; |   return return_value; | ||||||
| } | } | ||||||
| @@ -1169,6 +1288,8 @@ int main() | |||||||
|   char name7[] = "FILE1_+_CONTENTTYPE"; |   char name7[] = "FILE1_+_CONTENTTYPE"; | ||||||
|   char name8[] = "FILE1_+_FILE2"; |   char name8[] = "FILE1_+_FILE2"; | ||||||
|   char name9[] = "FILE1_+_FILE2_+_FILE3"; |   char name9[] = "FILE1_+_FILE2_+_FILE3"; | ||||||
|  |   char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3"; | ||||||
|  |   char name11[] = "FILECONTENT"; | ||||||
|   char value1[] = "value for simple COPYCONTENTS"; |   char value1[] = "value for simple COPYCONTENTS"; | ||||||
|   char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; |   char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; | ||||||
|   char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; |   char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; | ||||||
| @@ -1190,6 +1311,7 @@ int main() | |||||||
|   char buffer[4096]; |   char buffer[4096]; | ||||||
|   struct HttpPost *httppost=NULL; |   struct HttpPost *httppost=NULL; | ||||||
|   struct HttpPost *last_post=NULL; |   struct HttpPost *last_post=NULL; | ||||||
|  |   struct curl_forms forms[4]; | ||||||
|  |  | ||||||
|   struct FormData *form; |   struct FormData *form; | ||||||
|   struct Form formread; |   struct Form formread; | ||||||
| @@ -1244,6 +1366,21 @@ int main() | |||||||
|                   CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, |                   CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, | ||||||
|                   CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) |                   CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) | ||||||
|     ++errors; |     ++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); |   form=Curl_getFormData(httppost, &size); | ||||||
|  |  | ||||||
| @@ -1255,12 +1392,12 @@ int main() | |||||||
|  |  | ||||||
|     if(-1 == nread) |     if(-1 == nread) | ||||||
|       break; |       break; | ||||||
|     fwrite(buffer, nread, 1, stderr); |     fwrite(buffer, nread, 1, stdout); | ||||||
|   } while(1); |   } while(1); | ||||||
|  |  | ||||||
|   fprintf(stderr, "size: %d\n", size); |   fprintf(stdout, "size: %d\n", size); | ||||||
|   if (errors) |   if (errors) | ||||||
|     fprintf(stderr, "\n==> %d Test(s) failed!\n", errors); |     fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); | ||||||
|   else |   else | ||||||
|     fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); |     fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); | ||||||
|  |  | ||||||
| @@ -1327,6 +1464,6 @@ int main(int argc, char **argv) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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_connect(struct connectdata *conn); | ||||||
| CURLcode Curl_ftp_disconnect(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: */ | /* The kerberos stuff needs this: */ | ||||||
| int Curl_GetFTPResponse(int sockfd, char *buf, | int Curl_GetFTPResponse(char *buf, struct connectdata *conn, | ||||||
|                         struct connectdata *conn, |  | ||||||
|                         int *ftpcode); |                         int *ftpcode); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -2131,6 +2131,6 @@ main (ac, av) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -71,6 +71,6 @@ char *curl_getenv(const char *v) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data) | |||||||
|  |  | ||||||
|   info->httpcode = 0; |   info->httpcode = 0; | ||||||
|   info->httpversion=0; |   info->httpversion=0; | ||||||
|   info->filetime=0; |   info->filetime=-1; /* -1 is an illegal time and thus means unknown */ | ||||||
|  |  | ||||||
|   return CURLE_OK; |   return CURLE_OK; | ||||||
| } | } | ||||||
| @@ -138,6 +138,6 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -249,6 +249,6 @@ char *getpass(const char *prompt) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
							
								
								
									
										205
									
								
								lib/hostip.c
									
									
									
									
									
								
							
							
						
						
									
										205
									
								
								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 |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -55,6 +55,7 @@ | |||||||
|  |  | ||||||
| #include "urldata.h" | #include "urldata.h" | ||||||
| #include "sendf.h" | #include "sendf.h" | ||||||
|  | #include "hostip.h" | ||||||
|  |  | ||||||
| #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) | #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) | ||||||
| #include "inet_ntoa_r.h" | #include "inet_ntoa_r.h" | ||||||
| @@ -65,8 +66,168 @@ | |||||||
| #include "memdebug.h" | #include "memdebug.h" | ||||||
| #endif | #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 --- */ | /* --- 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) | static char *MakeIP(unsigned long num,char *addr, int addr_len) | ||||||
| { | { | ||||||
| #if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R) | #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); |   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 | /* 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 |    code, written by Bjorn Reese, it has since been patched and modified | ||||||
|    considerably. */ |    considerably. */ | ||||||
| @@ -119,9 +257,10 @@ struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
| #define INADDR_NONE (unsigned long) ~0 | #define INADDR_NONE (unsigned long) ~0 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| struct hostent *Curl_gethost(struct SessionHandle *data, | Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||||
|                              char *hostname, |                                 char *hostname, | ||||||
|                              char **bufp) |                                 int port, | ||||||
|  |                                 char **bufp) | ||||||
| { | { | ||||||
|   struct hostent *h = NULL; |   struct hostent *h = NULL; | ||||||
|   unsigned long in; |   unsigned long in; | ||||||
| @@ -137,6 +276,7 @@ struct hostent *Curl_gethost(struct SessionHandle *data, | |||||||
|     return NULL; /* major failure */ |     return NULL; /* major failure */ | ||||||
|   *bufp = buf; |   *bufp = buf; | ||||||
|  |  | ||||||
|  |   port=0; /* unused in IPv4 code */ | ||||||
|   ret = 0; /* to prevent the compiler warning */ |   ret = 0; /* to prevent the compiler warning */ | ||||||
|  |  | ||||||
|   if ( (in=inet_addr(hostname)) != INADDR_NONE ) { |   if ( (in=inet_addr(hostname)) != INADDR_NONE ) { | ||||||
| @@ -211,15 +351,22 @@ struct hostent *Curl_gethost(struct SessionHandle *data, | |||||||
|       free(buf); |       free(buf); | ||||||
|       *bufp=NULL; |       *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 | #endif | ||||||
|   } |   } | ||||||
|   return (h); |   return (h); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #endif /* end of IPv4-specific code */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								lib/hostip.h
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								lib/hostip.h
									
									
									
									
									
								
							| @@ -24,12 +24,24 @@ | |||||||
|  *****************************************************************************/ |  *****************************************************************************/ | ||||||
|  |  | ||||||
| struct addrinfo; | struct addrinfo; | ||||||
| struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | struct hostent; | ||||||
|                              char *hostname, | struct SessionHandle; | ||||||
|                              int port); |  | ||||||
|  |  | ||||||
| struct hostent *Curl_gethost(struct SessionHandle *data, | /* Get name info */ | ||||||
|                              char *hostname, | Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||||
|                              char **bufp); |                                 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 | #endif | ||||||
|   | |||||||
							
								
								
									
										134
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								lib/http.c
									
									
									
									
									
								
							| @@ -125,22 +125,27 @@ send_buffer *add_buffer_init(void) | |||||||
|  * add_buffer_send() sends a buffer and frees all associated memory. |  * add_buffer_send() sends a buffer and frees all associated memory. | ||||||
|  */ |  */ | ||||||
| static | 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; |   size_t amount; | ||||||
|  |   CURLcode result; | ||||||
|  |  | ||||||
|   if(conn->data->set.verbose) { |   if(conn->data->set.verbose) { | ||||||
|     fputs("> ", conn->data->set.err); |     fputs("> ", conn->data->set.err); | ||||||
|     /* this data _may_ contain binary stuff */ |     /* this data _may_ contain binary stuff */ | ||||||
|     fwrite(in->buffer, in->size_used, 1, conn->data->set.err); |     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) |   if(in->buffer) | ||||||
|     free(in->buffer); |     free(in->buffer); | ||||||
|   free(in); |   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 | static | ||||||
| int GetLine(int sockfd, char *buf, struct connectdata *conn) | int GetLine(int sockfd, char *ptr, struct connectdata *conn) | ||||||
| { | { | ||||||
|   ssize_t nread; |   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 */ |   /* get us a full line, terminated with a newline */ | ||||||
|   for(nread=0; |   for(nread=0; (nread<BUFSIZE); nread++, ptr++) { | ||||||
|       (nread<BUFSIZE) && read_rc; |  | ||||||
|       nread++, ptr++) { |  | ||||||
|     if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) || |     if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) || | ||||||
|        (nread <= 0) || |        (nread <= 0) || (*ptr == '\n')) | ||||||
|        (*ptr == '\n')) |  | ||||||
|       break; |       break; | ||||||
|   } |   } | ||||||
|   *ptr=0; /* zero terminate */ |   *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; |   return nread>0?nread:0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -264,24 +256,33 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | |||||||
|   int httperror=0; |   int httperror=0; | ||||||
|   int subversion=0; |   int subversion=0; | ||||||
|   struct SessionHandle *data=conn->data; |   struct SessionHandle *data=conn->data; | ||||||
|  |   CURLcode result; | ||||||
|  |  | ||||||
|   infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); |   infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); | ||||||
|  |  | ||||||
|   /* OK, now send the connect request to the proxy */ |   /* OK, now send the connect request to the proxy */ | ||||||
|   Curl_sendf(tunnelsocket, conn, |   result = | ||||||
|              "CONNECT %s:%d HTTP/1.0\015\012" |     Curl_sendf(tunnelsocket, conn, | ||||||
|              "%s" |                "CONNECT %s:%d HTTP/1.0\015\012" | ||||||
|              "%s" |                "%s" | ||||||
|              "\r\n", |                "%s" | ||||||
|              hostname, remote_port, |                "\r\n", | ||||||
|              (conn->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"", |                hostname, remote_port, | ||||||
|              (data->set.useragent?conn->allocptr.uagent:"") |                (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 */ |   /* wait for the proxy to send us a HTTP/1.0 200 OK header */ | ||||||
|   while(GetLine(tunnelsocket, data->state.buffer, conn)) { |   while(GetLine(tunnelsocket, data->state.buffer, conn)) { | ||||||
|     if('\r' == data->state.buffer[0]) |     if('\r' == data->state.buffer[0]) | ||||||
|       break; /* end of headers */ |       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", |     if(2 == sscanf(data->state.buffer, "HTTP/1.%d %d", | ||||||
|                    &subversion, |                    &subversion, | ||||||
|                    &httperror)) { |                    &httperror)) { | ||||||
| @@ -341,15 +342,6 @@ CURLcode Curl_http_connect(struct connectdata *conn) | |||||||
|   return CURLE_OK; |   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) | CURLcode Curl_http_done(struct connectdata *conn) | ||||||
| { | { | ||||||
|   struct SessionHandle *data; |   struct SessionHandle *data; | ||||||
| @@ -371,6 +363,13 @@ CURLcode Curl_http_done(struct connectdata *conn) | |||||||
|     *bytecount = http->readbytecount + http->writebytecount; |     *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; |   return CURLE_OK; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -574,6 +573,10 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   do { |   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; |     send_buffer *req_buffer; | ||||||
|     struct curl_slist *headers=data->set.headers; |     struct curl_slist *headers=data->set.headers; | ||||||
|  |  | ||||||
| @@ -583,7 +586,7 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|     /* add the main request stuff */ |     /* add the main request stuff */ | ||||||
|     add_bufferf(req_buffer, |     add_bufferf(req_buffer, | ||||||
|                 "%s " /* GET/HEAD/POST/PUT */ |                 "%s " /* GET/HEAD/POST/PUT */ | ||||||
|                 "%s HTTP/1.1\r\n" /* path */ |                 "%s HTTP/%s\r\n" /* path */ | ||||||
|                 "%s" /* proxyuserpwd */ |                 "%s" /* proxyuserpwd */ | ||||||
|                 "%s" /* userpwd */ |                 "%s" /* userpwd */ | ||||||
|                 "%s" /* range */ |                 "%s" /* range */ | ||||||
| @@ -599,7 +602,7 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|                  ((HTTPREQ_POST == data->set.httpreq) || |                  ((HTTPREQ_POST == data->set.httpreq) || | ||||||
|                   (HTTPREQ_POST_FORM == data->set.httpreq))?"POST": |                   (HTTPREQ_POST_FORM == data->set.httpreq))?"POST": | ||||||
|                  (HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"), |                  (HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"), | ||||||
|                 ppath, |                 ppath, httpstring, | ||||||
|                 (conn->bits.proxy_user_passwd && |                 (conn->bits.proxy_user_passwd && | ||||||
|                  conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"", |                  conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"", | ||||||
|                 (conn->bits.user_passwd && conn->allocptr.userpwd)? |                 (conn->bits.user_passwd && conn->allocptr.userpwd)? | ||||||
| @@ -748,14 +751,16 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|       Curl_pgrsSetUploadSize(data, http->postsize); |       Curl_pgrsSetUploadSize(data, http->postsize); | ||||||
|  |  | ||||||
|       /* fire away the whole request to the server */ |       /* fire away the whole request to the server */ | ||||||
|       data->info.request_size =  |       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); |                                &data->info.request_size); | ||||||
|  |       if(result) | ||||||
|       /* setup variables for the upcoming transfer */ |         failf(data, "Failed sending POST request"); | ||||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, |       else | ||||||
|                              &http->readbytecount, |         /* setup variables for the upcoming transfer */ | ||||||
|                              conn->firstsocket, |         result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, | ||||||
|                              &http->writebytecount); |                                &http->readbytecount, | ||||||
|  |                                conn->firstsocket, | ||||||
|  |                                &http->writebytecount); | ||||||
|       if(result) { |       if(result) { | ||||||
|         Curl_formclean(http->sendit); /* free that whole lot */ |         Curl_formclean(http->sendit); /* free that whole lot */ | ||||||
|         return result; |         return result; | ||||||
| @@ -776,14 +781,16 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|       Curl_pgrsSetUploadSize(data, data->set.infilesize); |       Curl_pgrsSetUploadSize(data, data->set.infilesize); | ||||||
|  |  | ||||||
|       /* this sends the buffer and frees all the buffer resources */ |       /* this sends the buffer and frees all the buffer resources */ | ||||||
|       data->info.request_size =  |       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); |                                &data->info.request_size); | ||||||
|  |       if(result) | ||||||
|       /* prepare for transfer */ |         failf(data, "Faied sending POST request"); | ||||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, |       else | ||||||
|                         &http->readbytecount, |         /* prepare for transfer */ | ||||||
|                         conn->firstsocket, |         result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, | ||||||
|                         &http->writebytecount); |                                &http->readbytecount, | ||||||
|  |                                conn->firstsocket, | ||||||
|  |                                &http->writebytecount); | ||||||
|       if(result) |       if(result) | ||||||
|         return result; |         return result; | ||||||
|        |        | ||||||
| @@ -833,12 +840,15 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|         add_buffer(req_buffer, "\r\n", 2); |         add_buffer(req_buffer, "\r\n", 2); | ||||||
|  |  | ||||||
|       /* issue the request */ |       /* issue the request */ | ||||||
|       data->info.request_size =  |       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); |                                &data->info.request_size); | ||||||
|  |  | ||||||
|       /* HTTP GET/HEAD download: */ |       if(result) | ||||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, bytecount, |         failf(data, "Failed sending HTTP request"); | ||||||
|                         -1, NULL); /* nothing to upload */ |       else | ||||||
|  |         /* HTTP GET/HEAD download: */ | ||||||
|  |         result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, bytecount, | ||||||
|  |                                -1, NULL); /* nothing to upload */ | ||||||
|     } |     } | ||||||
|     if(result) |     if(result) | ||||||
|       return result; |       return result; | ||||||
| @@ -853,6 +863,6 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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(struct connectdata *conn); | ||||||
| CURLcode Curl_http_done(struct connectdata *conn); | CURLcode Curl_http_done(struct connectdata *conn); | ||||||
| CURLcode Curl_http_connect(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 */ | /* The following functions are defined in http_chunks.c */ | ||||||
| void Curl_httpchunk_init(struct connectdata *conn); | void Curl_httpchunk_init(struct connectdata *conn); | ||||||
|   | |||||||
| @@ -225,6 +225,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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; |   u_int32_t cs; | ||||||
|   struct krb4_data *d = app_data; |   struct krb4_data *d = app_data; | ||||||
|   struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR; |   struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR; | ||||||
|   char *host = conn->hp->h_name; |   char *host = conn->hostaddr->h_name; | ||||||
|   ssize_t nread; |   ssize_t nread; | ||||||
|   int l = sizeof(conn->local_addr); |   int l = sizeof(conn->local_addr); | ||||||
|  |  | ||||||
| @@ -245,12 +245,12 @@ krb4_auth(void *app_data, struct connectdata *conn) | |||||||
|     return AUTH_CONTINUE; |     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, |   nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL); | ||||||
|                               conn->data->state.buffer, conn, NULL); |  | ||||||
|   if(nread < 0) |   if(nread < 0) | ||||||
|     return /*CURLE_OPERATION_TIMEOUTED*/-1; |     return -1; | ||||||
|   free(p); |   free(p); | ||||||
|  |  | ||||||
|   if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){ |   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); |   save = Curl_set_command_prot(conn, prot_private); | ||||||
|  |  | ||||||
|   Curl_ftpsendf(conn->firstsocket, conn, |   if(Curl_ftpsendf(conn, "SITE KAUTH %s", conn->data->state.user)) | ||||||
|                 "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); |                               conn, NULL); | ||||||
|   if(nread < 0) |   if(nread < 0) | ||||||
|     return /*CURLE_OPERATION_TIMEOUTED*/; |     return /*CURLE_OPERATION_TIMEOUTED*/; | ||||||
| @@ -363,7 +363,7 @@ void Curl_krb_kauth(struct connectdata *conn) | |||||||
|   if (strcmp ((char*)tktcopy.dat + 8, |   if (strcmp ((char*)tktcopy.dat + 8, | ||||||
|               KRB_TICKET_GRANTING_TICKET) != 0) { |               KRB_TICKET_GRANTING_TICKET) != 0) { | ||||||
|     afs_string_to_key (passwd, |     afs_string_to_key (passwd, | ||||||
|                        krb_realmofhost(/*hostname*/conn->hp->h_name), |                        krb_realmofhost(conn->hostaddr->h_name), | ||||||
|                        &key); |                        &key); | ||||||
|     des_key_sched (&key, schedule); |     des_key_sched (&key, schedule); | ||||||
|     des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat, |     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); |   memset (tktcopy.dat, 0, tktcopy.length); | ||||||
|  |  | ||||||
|   Curl_ftpsendf(conn->firstsocket, conn, |   if(Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p)) | ||||||
|                 "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); |                               conn, NULL); | ||||||
|   if(nread < 0) |   if(nread < 0) | ||||||
|     return /*CURLE_OPERATION_TIMEOUTED*/; |     return /*CURLE_OPERATION_TIMEOUTED*/; | ||||||
| @@ -397,6 +397,6 @@ void Curl_krb_kauth(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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 |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -47,6 +47,7 @@ | |||||||
| #include <curl/curl.h> | #include <curl/curl.h> | ||||||
| #include "sendf.h" | #include "sendf.h" | ||||||
| #include "escape.h" | #include "escape.h" | ||||||
|  | #include "transfer.h" | ||||||
|  |  | ||||||
| #define _MPRINTF_REPLACE /* use our functions only */ | #define _MPRINTF_REPLACE /* use our functions only */ | ||||||
| #include <curl/mprintf.h> | #include <curl/mprintf.h> | ||||||
| @@ -211,6 +212,9 @@ CURLcode Curl_ldap(struct connectdata *conn) | |||||||
|   } |   } | ||||||
|   DynaClose(); |   DynaClose(); | ||||||
|  |  | ||||||
|  |   /* no data to transfer */ | ||||||
|  |   Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); | ||||||
|  |    | ||||||
|   return status; |   return status; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -218,6 +222,6 @@ CURLcode Curl_ldap(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -31,4 +31,6 @@ EXPORTS | |||||||
|  	curl_mvfprintf @ 22 ; |  	curl_mvfprintf @ 22 ; | ||||||
| 	curl_strequal @ 23 ; | 	curl_strequal @ 23 ; | ||||||
| 	curl_strnequal @ 24 ; | 	curl_strnequal @ 24 ; | ||||||
|  |         curl_easy_duphandle @ 25 ; | ||||||
|  |         curl_formadd @ 26 ; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,15 +60,19 @@ FILE *logfile; | |||||||
| /* this sets the log file name */ | /* this sets the log file name */ | ||||||
| void curl_memdebug(const char *logname) | void curl_memdebug(const char *logname) | ||||||
| { | { | ||||||
|   logfile = fopen(logname, "w"); |   if(logname) | ||||||
|  |     logfile = fopen(logname, "w"); | ||||||
|  |   else | ||||||
|  |     logfile = stderr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void *curl_domalloc(size_t size, int line, const char *source) | void *curl_domalloc(size_t size, int line, const char *source) | ||||||
| { | { | ||||||
|   void *mem=(malloc)(size); |   void *mem=(malloc)(size); | ||||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d malloc(%d) = %p\n", |   if(logfile) | ||||||
|           source, line, size, mem); |     fprintf(logfile, "MEM %s:%d malloc(%d) = %p\n", | ||||||
|  |             source, line, size, mem); | ||||||
|   return mem; |   return mem; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -85,16 +89,18 @@ char *curl_dostrdup(const char *str, int line, const char *source) | |||||||
|  |  | ||||||
|   mem=(strdup)(str); |   mem=(strdup)(str); | ||||||
|   len=strlen(str)+1; |   len=strlen(str)+1; | ||||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d strdup(%p) (%d) = %p\n", |   if(logfile) | ||||||
|           source, line, str, len, mem); |     fprintf(logfile, "MEM %s:%d strdup(%p) (%d) = %p\n", | ||||||
|  |             source, line, str, len, mem); | ||||||
|   return mem; |   return mem; | ||||||
| } | } | ||||||
|  |  | ||||||
| void *curl_dorealloc(void *ptr, size_t size, int line, const char *source) | void *curl_dorealloc(void *ptr, size_t size, int line, const char *source) | ||||||
| { | { | ||||||
|   void *mem=(realloc)(ptr, size); |   void *mem=(realloc)(ptr, size); | ||||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d realloc(%p, %d) = %p\n", |   if(logfile) | ||||||
|           source, line, ptr, size, mem); |     fprintf(logfile, "MEM %s:%d realloc(%p, %d) = %p\n", | ||||||
|  |             source, line, ptr, size, mem); | ||||||
|   return mem; |   return mem; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -108,15 +114,16 @@ void curl_dofree(void *ptr, int line, const char *source) | |||||||
|  |  | ||||||
|   (free)(ptr); |   (free)(ptr); | ||||||
|  |  | ||||||
|   fprintf(logfile?logfile:stderr, "MEM %s:%d free(%p)\n", |   if(logfile) | ||||||
|           source, line, ptr); |     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 curl_socket(int domain, int type, int protocol, int line, char *source) | ||||||
| { | { | ||||||
|   int sockfd=(socket)(domain, type, protocol); |   int sockfd=(socket)(domain, type, protocol); | ||||||
|   fprintf(logfile?logfile:stderr, "FD %s:%d socket() = %d\n", |   if(logfile) | ||||||
|           source, line, sockfd); |     fprintf(logfile, "FD %s:%d socket() = %d\n", | ||||||
|  |             source, line, sockfd); | ||||||
|   return sockfd; |   return sockfd; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -124,8 +131,9 @@ int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen, | |||||||
|                 int line, const char *source) |                 int line, const char *source) | ||||||
| { | { | ||||||
|   int sockfd=(accept)(s, addr, addrlen); |   int sockfd=(accept)(s, addr, addrlen); | ||||||
|   fprintf(logfile?logfile:stderr, "FD %s:%d accept() = %d\n", |   if(logfile) | ||||||
|           source, line, sockfd); |     fprintf(logfile, "FD %s:%d accept() = %d\n", | ||||||
|  |             source, line, sockfd); | ||||||
|   return sockfd; |   return sockfd; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -133,8 +141,9 @@ int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen, | |||||||
| int curl_sclose(int sockfd, int line, char *source) | int curl_sclose(int sockfd, int line, char *source) | ||||||
| { | { | ||||||
|   int res=sclose(sockfd); |   int res=sclose(sockfd); | ||||||
|   fprintf(logfile?logfile:stderr, "FD %s:%d sclose(%d)\n", |   if(logfile) | ||||||
|           source, line, sockfd); |     fprintf(logfile, "FD %s:%d sclose(%d)\n", | ||||||
|  |             source, line, sockfd); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -142,16 +151,18 @@ FILE *curl_fopen(const char *file, const char *mode, | |||||||
|                  int line, const char *source) |                  int line, const char *source) | ||||||
| { | { | ||||||
|   FILE *res=(fopen)(file, mode); |   FILE *res=(fopen)(file, mode); | ||||||
|   fprintf(logfile?logfile:stderr, "FILE %s:%d fopen(\"%s\") = %p\n", |   if(logfile) | ||||||
|           source, line, file, res); |     fprintf(logfile, "FILE %s:%d fopen(\"%s\") = %p\n", | ||||||
|  |             source, line, file, res); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| int curl_fclose(FILE *file, int line, const char *source) | int curl_fclose(FILE *file, int line, const char *source) | ||||||
| { | { | ||||||
|   int res=(fclose)(file); |   int res=(fclose)(file); | ||||||
|   fprintf(logfile?logfile:stderr, "FILE %s:%d fclose(%p)\n", |   if(logfile) | ||||||
|           source, line, file); |     fprintf(logfile, "FILE %s:%d fclose(%p)\n", | ||||||
|  |             source, line, file); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -161,6 +172,6 @@ int curl_fclose(FILE *file, int line, const char *source) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ | |||||||
| #include <memory.h> | #include <memory.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | extern FILE *logfile; | ||||||
|  |  | ||||||
| /* memory functions */ | /* memory functions */ | ||||||
| void *curl_domalloc(size_t size, int line, const char *source); | void *curl_domalloc(size_t size, int line, const char *source); | ||||||
| void *curl_dorealloc(void *ptr, 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)\ | #define accept(sock,addr,len)\ | ||||||
|  curl_accept(sock,addr,len,__LINE__,__FILE__) |  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! */ | /* sclose is probably already defined, redefine it! */ | ||||||
| #undef sclose | #undef sclose | ||||||
| #define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) | #define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) | ||||||
|   | |||||||
| @@ -1237,6 +1237,6 @@ int main() | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -206,6 +206,6 @@ int main(int argc, char **argv) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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 |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * 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)) { |   if(bytes < (100*ONE_MEGABYTE)) { | ||||||
|     /* 'XX.XM' is good as long as we're less than 100 megs */ |     /* '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; |     return max5; | ||||||
|   } |   } | ||||||
|   sprintf(max5, "%4dM", (int)bytes/ONE_MEGABYTE); |   sprintf(max5, "%4dM", (int)bytes/ONE_MEGABYTE); | ||||||
| @@ -118,16 +118,16 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer) | |||||||
|     break; |     break; | ||||||
|  |  | ||||||
|   case TIMER_NAMELOOKUP: |   case TIMER_NAMELOOKUP: | ||||||
|     data->progress.t_nslookup += Curl_tvdiff(Curl_tvnow(), |     data->progress.t_nslookup += | ||||||
|                                         data->progress.t_startsingle); |       (double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000; | ||||||
|     break; |     break; | ||||||
|   case TIMER_CONNECT: |   case TIMER_CONNECT: | ||||||
|     data->progress.t_connect += Curl_tvdiff(Curl_tvnow(), |     data->progress.t_connect += | ||||||
|                                        data->progress.t_startsingle); |       (double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000; | ||||||
|     break; |     break; | ||||||
|   case TIMER_PRETRANSFER: |   case TIMER_PRETRANSFER: | ||||||
|     data->progress.t_pretransfer += Curl_tvdiff(Curl_tvnow(), |     data->progress.t_pretransfer += | ||||||
|                                            data->progress.t_startsingle); |       (double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000; | ||||||
|     break; |     break; | ||||||
|   case TIMER_POSTRANSFER: |   case TIMER_POSTRANSFER: | ||||||
|     /* this is the normal end-of-transfer thing */ |     /* this is the normal end-of-transfer thing */ | ||||||
| @@ -187,12 +187,14 @@ int Curl_pgrsUpdate(struct connectdata *conn) | |||||||
|  |  | ||||||
|   double total_transfer; |   double total_transfer; | ||||||
|   double total_expected_transfer; |   double total_expected_transfer; | ||||||
|  |   double timespent; | ||||||
|  |  | ||||||
|   struct SessionHandle *data = conn->data; |   struct SessionHandle *data = conn->data; | ||||||
|  |  | ||||||
|   int nowindex = data->progress.speeder_c% CURR_TIME; |   int nowindex = data->progress.speeder_c% CURR_TIME; | ||||||
|   int checkindex; |   int checkindex; | ||||||
|   int count; |  | ||||||
|  |   int countindex; /* amount of seconds stored in the speeder array */ | ||||||
|  |  | ||||||
|   char time_left[10]; |   char time_left[10]; | ||||||
|   char time_total[10]; |   char time_total[10]; | ||||||
| @@ -222,14 +224,18 @@ int Curl_pgrsUpdate(struct connectdata *conn) | |||||||
|  |  | ||||||
|   now = Curl_tvnow(); /* what time is it */ |   now = Curl_tvnow(); /* what time is it */ | ||||||
|  |  | ||||||
|   /* The exact time spent so far */ |   /* The exact time spent so far (from the start) */ | ||||||
|   data->progress.timespent = Curl_tvdiff (now, data->progress.start); |   timespent = (double)Curl_tvdiff (now, data->progress.start)/1000; | ||||||
|  |  | ||||||
|  |   data->progress.timespent = (long)timespent; | ||||||
|  |  | ||||||
|   /* The average download speed this far */ |   /* 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 */ |   /* 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)) |   if(data->progress.lastshow == Curl_tvlong(now)) | ||||||
|     return 0; /* never update this more than once a second if the end isn't  |     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; |   data->progress.lastshow = now.tv_sec; | ||||||
|  |  | ||||||
|   /* Let's do the "current speed" thing, which should use the fastest |   /* 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.speeder[ nowindex ] = | ||||||
|     data->progress.downloaded>data->progress.uploaded? |     data->progress.downloaded>data->progress.uploaded? | ||||||
|     data->progress.downloaded:data->progress.uploaded; |     data->progress.downloaded:data->progress.uploaded; | ||||||
|   data->progress.speeder_c++; /* increase */ |  | ||||||
|   count = ((data->progress.speeder_c>=CURR_TIME)? |  | ||||||
|            CURR_TIME:data->progress.speeder_c) - 1; |  | ||||||
|   checkindex = (data->progress.speeder_c>=CURR_TIME)? |  | ||||||
|     data->progress.speeder_c%CURR_TIME:0; |  | ||||||
|  |  | ||||||
|   /* find out the average speed the last CURR_TIME seconds */ |   /* remember the exact time for this moment */ | ||||||
|   data->progress.current_speed = |   data->progress.speeder_time [ nowindex ] = now; | ||||||
|     (data->progress.speeder[nowindex]- |  | ||||||
|      data->progress.speeder[checkindex])/(count?count:1); |   /* 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; | ||||||
|  |  | ||||||
|  |     /* 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])/((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) |   if(data->progress.flags & PGRS_HIDE) | ||||||
|     return 0; |     return 0; | ||||||
|  |  | ||||||
|   else if(data->set.fprogress) { |   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, |     result= data->set.fprogress(data->set.progress_client, | ||||||
|                                 data->progress.size_dl, |                                 data->progress.size_dl, | ||||||
|                                 data->progress.downloaded, |                                 data->progress.downloaded, | ||||||
| @@ -265,7 +303,7 @@ int Curl_pgrsUpdate(struct connectdata *conn) | |||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|       /* Figure out the estimated time of arrival for the upload */ |   /* Figure out the estimated time of arrival for the upload */ | ||||||
|   if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && data->progress.ulspeed){ |   if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && data->progress.ulspeed){ | ||||||
|     ulestimate = data->progress.size_ul / data->progress.ulspeed; |     ulestimate = data->progress.size_ul / data->progress.ulspeed; | ||||||
|     ulpercen = (data->progress.uploaded / data->progress.size_ul)*100; |     ulpercen = (data->progress.uploaded / data->progress.size_ul)*100; | ||||||
| @@ -278,12 +316,12 @@ int Curl_pgrsUpdate(struct connectdata *conn) | |||||||
|   } |   } | ||||||
|      |      | ||||||
|   /* Now figure out which of them that is slower and use for the for |   /* Now figure out which of them that is slower and use for the for | ||||||
|          total estimate! */ |      total estimate! */ | ||||||
|   total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; |   total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* If we have a total estimate, we can display that and the expected |   /* If we have a total estimate, we can display that and the expected | ||||||
|          time left */ |      time left */ | ||||||
|   if(total_estimate) { |   if(total_estimate) { | ||||||
|     time2str(time_left, total_estimate-(int) data->progress.timespent);  |     time2str(time_left, total_estimate-(int) data->progress.timespent);  | ||||||
|     time2str(time_total, total_estimate); |     time2str(time_total, total_estimate); | ||||||
| @@ -337,6 +375,6 @@ int Curl_pgrsUpdate(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -413,33 +413,34 @@ sec_prot_internal(struct connectdata *conn, int level) | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   if(level){ |   if(level){ | ||||||
|     Curl_ftpsendf(conn->firstsocket, conn, |     if(Curl_ftpsendf(conn, "PBSZ %u", s)) | ||||||
|                   "PBSZ %u", s); |       return -1; | ||||||
|     /* wait for feedback */ |  | ||||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, |     nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL); | ||||||
|                                 conn->data->state.buffer, conn, NULL); |  | ||||||
|     if(nread < 0) |     if(nread < 0) | ||||||
|       return /*CURLE_OPERATION_TIMEOUTED*/-1; |       return -1; | ||||||
|     if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){ |  | ||||||
|  |     if(conn->data->state.buffer[0] != '2'){ | ||||||
|       failf(conn->data, "Failed to set protection buffer size.\n"); |       failf(conn->data, "Failed to set protection buffer size.\n"); | ||||||
|       return -1; |       return -1; | ||||||
|     } |     } | ||||||
|     conn->buffer_size = s; |     conn->buffer_size = s; | ||||||
|     p = strstr(/*reply_string*/conn->data->state.buffer, "PBSZ="); |  | ||||||
|  |     p = strstr(conn->data->state.buffer, "PBSZ="); | ||||||
|     if(p) |     if(p) | ||||||
|       sscanf(p, "PBSZ=%u", &s); |       sscanf(p, "PBSZ=%u", &s); | ||||||
|     if(s < conn->buffer_size) |     if(s < conn->buffer_size) | ||||||
|       conn->buffer_size = s; |       conn->buffer_size = s; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Curl_ftpsendf(conn->firstsocket, conn, |   if(Curl_ftpsendf(conn, "PROT %c", level["CSEP"])) | ||||||
|                 "PROT %c", level["CSEP"]); |     return -1; | ||||||
|   /* wait for feedback */ |  | ||||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, |   nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, NULL); | ||||||
|                               conn->data->state.buffer, conn, NULL); |  | ||||||
|   if(nread < 0) |   if(nread < 0) | ||||||
|     return /*CURLE_OPERATION_TIMEOUTED*/-1; |     return -1; | ||||||
|   if(/*ret != COMPLETE*/conn->data->state.buffer[0] != '2'){ |  | ||||||
|  |   if(conn->data->state.buffer[0] != '2'){ | ||||||
|     failf(conn->data, "Failed to set protection level.\n"); |     failf(conn->data, "Failed to set protection level.\n"); | ||||||
|     return -1; |     return -1; | ||||||
|   } |   } | ||||||
| @@ -473,6 +474,7 @@ Curl_sec_login(struct connectdata *conn) | |||||||
|   struct Curl_sec_client_mech **m; |   struct Curl_sec_client_mech **m; | ||||||
|   ssize_t nread; |   ssize_t nread; | ||||||
|   struct SessionHandle *data=conn->data; |   struct SessionHandle *data=conn->data; | ||||||
|  |   int ftpcode; | ||||||
|  |  | ||||||
|   for(m = mechs; *m && (*m)->name; m++) { |   for(m = mechs; *m && (*m)->name; m++) { | ||||||
|     void *tmp; |     void *tmp; | ||||||
| @@ -489,31 +491,35 @@ Curl_sec_login(struct connectdata *conn) | |||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
|     infof(data, "Trying %s...\n", (*m)->name); |     infof(data, "Trying %s...\n", (*m)->name); | ||||||
|     /*ret = command("AUTH %s", (*m)->name);***/ |  | ||||||
|     Curl_ftpsendf(conn->firstsocket, conn, |     if(Curl_ftpsendf(conn, "AUTH %s", (*m)->name)) | ||||||
|                   "AUTH %s", (*m)->name); |       return -1; | ||||||
|     /* wait for feedback */ |  | ||||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, |     nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode); | ||||||
|                                 conn->data->state.buffer, conn, NULL); |  | ||||||
|     if(nread < 0) |     if(nread < 0) | ||||||
|       return /*CURLE_OPERATION_TIMEOUTED*/-1; |       return -1; | ||||||
|     if(/*ret != CONTINUE*/conn->data->state.buffer[0] != '3'){ |  | ||||||
|       if(/*code == 504*/strncmp(conn->data->state.buffer,"504",3) == 0) { |     if(conn->data->state.buffer[0] != '3'){ | ||||||
|  |       switch(ftpcode) { | ||||||
|  |       case 504: | ||||||
|         infof(data, |         infof(data, | ||||||
|               "%s is not supported by the server.\n", (*m)->name); |               "%s is not supported by the server.\n", (*m)->name); | ||||||
|       } |         break; | ||||||
|       else if(/*code == 534*/strncmp(conn->data->state.buffer,"534",3) == 0) { |       case 534: | ||||||
|         infof(data, "%s rejected as security mechanism.\n", (*m)->name); |         infof(data, "%s rejected as security mechanism.\n", (*m)->name); | ||||||
|       } |         break; | ||||||
|       else if(/*ret == ERROR*/conn->data->state.buffer[0] == '5') { |       default: | ||||||
|         infof(data, "The server doesn't support the FTP " |         if(conn->data->state.buffer[0] == '5') { | ||||||
|               "security extensions.\n"); |           infof(data, "The server doesn't support the FTP " | ||||||
|         return -1; |                 "security extensions.\n"); | ||||||
|  |           return -1; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|       } |       } | ||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ret = (*(*m)->auth)(conn->app_data, /*host***/conn); |     ret = (*(*m)->auth)(conn->app_data, conn); | ||||||
| 	 | 	 | ||||||
|     if(ret == AUTH_CONTINUE) |     if(ret == AUTH_CONTINUE) | ||||||
|       continue; |       continue; | ||||||
| @@ -551,6 +557,6 @@ Curl_sec_end(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								lib/sendf.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib/sendf.c
									
									
									
									
									
								
							| @@ -140,17 +140,20 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...) | |||||||
| { | { | ||||||
|   va_list ap; |   va_list ap; | ||||||
|   va_start(ap, fmt); |   va_start(ap, fmt); | ||||||
|   if(data->set.errorbuffer) |   if(data->set.errorbuffer && !data->state.errorbuf) { | ||||||
|     vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap); |     vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap); | ||||||
|  |     data->state.errorbuf = TRUE; /* wrote error string */ | ||||||
|  |   } | ||||||
|   va_end(ap); |   va_end(ap); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Curl_sendf() sends formated data to the server */ | /* 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, ...) |                     const char *fmt, ...) | ||||||
| { | { | ||||||
|   struct SessionHandle *data = conn->data; |   struct SessionHandle *data = conn->data; | ||||||
|   size_t bytes_written; |   size_t bytes_written; | ||||||
|  |   CURLcode result; | ||||||
|   char *s; |   char *s; | ||||||
|   va_list ap; |   va_list ap; | ||||||
|   va_start(ap, fmt); |   va_start(ap, fmt); | ||||||
| @@ -162,11 +165,11 @@ size_t Curl_sendf(int sockfd, struct connectdata *conn, | |||||||
|     fprintf(data->set.err, "> %s", s); |     fprintf(data->set.err, "> %s", s); | ||||||
|  |  | ||||||
|   /* Write the buffer to the socket */ |   /* 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 */ |   free(s); /* free the output string */ | ||||||
|  |  | ||||||
|   return bytes_written; |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -211,7 +214,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd, | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   *written = bytes_written; |   *written = bytes_written; | ||||||
|   return CURLE_OK; |   return (bytes_written==len)?CURLE_OK:CURLE_WRITE_ERROR; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* client_write() sends data to the write callback(s) | /* client_write() sends data to the write callback(s) | ||||||
| @@ -296,6 +299,6 @@ CURLcode Curl_read(struct connectdata *conn, int sockfd, | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ | |||||||
|  * $Id$ |  * $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_infof(struct SessionHandle *, const char *fmt, ...); | ||||||
| void Curl_failf(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 | #else | ||||||
| #define sclose(x) close(x) | #define sclose(x) close(x) | ||||||
| #define sread(x,y,z) read(x,y,z) | #define sread(x,y,z) recv(x,y,z,0) | ||||||
| #define swrite(x,y,z) write(x,y,z) | #define swrite(x,y,z) send(x,y,z,0) | ||||||
| #define myalarm(x) alarm(x) | #define myalarm(x) alarm(x) | ||||||
|  |  | ||||||
| #define PATH_CHAR     ":" | #define PATH_CHAR     ":" | ||||||
| @@ -144,4 +144,19 @@ int fileno( FILE *stream); | |||||||
|  |  | ||||||
| #endif | #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 */ | #endif /* __CONFIG_H */ | ||||||
|   | |||||||
| @@ -51,7 +51,8 @@ CURLcode Curl_speedcheck(struct SessionHandle *data, | |||||||
|        for "low speed time" seconds we consider that enough reason |        for "low speed time" seconds we consider that enough reason | ||||||
|        to abort the download. */ |        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 */ |       /* we have been this slow for long enough, now die */ | ||||||
|       failf(data, |       failf(data, | ||||||
| 	    "Operation too slow. " | 	    "Operation too slow. " | ||||||
| @@ -72,6 +73,6 @@ CURLcode Curl_speedcheck(struct SessionHandle *data, | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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, |     if (SSL_CTX_use_certificate_file(conn->ssl.ctx, | ||||||
| 				     cert_file, | 				     cert_file, | ||||||
| 				     SSL_FILETYPE_PEM) <= 0) { | 				     SSL_FILETYPE_PEM) != 1) { | ||||||
|       failf(data, "unable to set certificate file (wrong password?)\n"); |       failf(data, "unable to set certificate file (wrong password?)\n"); | ||||||
|       return(0); |       return(0); | ||||||
|     } |     } | ||||||
| @@ -209,7 +209,7 @@ int cert_stuff(struct connectdata *conn, | |||||||
|  |  | ||||||
|     if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx, |     if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx, | ||||||
| 				    key_file, | 				    key_file, | ||||||
| 				    SSL_FILETYPE_PEM) <= 0) { | 				    SSL_FILETYPE_PEM) != 1) { | ||||||
|       failf(data, "unable to set public key file\n"); |       failf(data, "unable to set public key file\n"); | ||||||
|       return(0); |       return(0); | ||||||
|     } |     } | ||||||
| @@ -612,7 +612,10 @@ Curl_SSLConnect(struct connectdata *conn) | |||||||
|   SSL_set_fd (conn->ssl.handle, conn->firstsocket); |   SSL_set_fd (conn->ssl.handle, conn->firstsocket); | ||||||
|   err = SSL_connect (conn->ssl.handle); |   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();  |     err = ERR_get_error();  | ||||||
|     failf(data, "SSL: %s", ERR_error_string(err, NULL)); |     failf(data, "SSL: %s", ERR_error_string(err, NULL)); | ||||||
|     return CURLE_SSL_CONNECT_ERROR; |     return CURLE_SSL_CONNECT_ERROR; | ||||||
| @@ -722,6 +725,6 @@ Curl_SSLConnect(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * 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> | #include <errno.h> | ||||||
|  |  | ||||||
| #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) | #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) | ||||||
| #include <winsock.h> | #include <winsock2.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <io.h> | #include <io.h> | ||||||
| #else | #else | ||||||
| @@ -152,8 +152,8 @@ struct TELNET { | |||||||
|   int him[256];  |   int him[256];  | ||||||
|   int himq[256];  |   int himq[256];  | ||||||
|   int him_preferred[256];  |   int him_preferred[256];  | ||||||
|   char *subopt_ttype;             /* Set with suboption TTYPE */ |   char subopt_ttype[32];             /* Set with suboption TTYPE */ | ||||||
|   char *subopt_xdisploc;          /* Set with suboption XDISPLOC */ |   char subopt_xdisploc[128];          /* Set with suboption XDISPLOC */ | ||||||
|   struct curl_slist *telnet_vars; /* Environment variables */ |   struct curl_slist *telnet_vars; /* Environment variables */ | ||||||
|  |  | ||||||
|   /* suboptions */ |   /* suboptions */ | ||||||
| @@ -765,14 +765,16 @@ static int check_telnet_options(struct connectdata *conn) | |||||||
|  |  | ||||||
|       /* Terminal type */ |       /* Terminal type */ | ||||||
|       if(strequal(option_keyword, "TTYPE")) { |       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; |         tn->us_preferred[TELOPT_TTYPE] = YES; | ||||||
|         continue; |         continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       /* Display variable */ |       /* Display variable */ | ||||||
|       if(strequal(option_keyword, "XDISPLOC")) { |       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; |         tn->us_preferred[TELOPT_XDISPLOC] = YES; | ||||||
|         continue; |         continue; | ||||||
|       } |       } | ||||||
| @@ -1033,9 +1035,16 @@ CURLcode Curl_telnet(struct connectdata *conn) | |||||||
|   CURLcode code; |   CURLcode code; | ||||||
|   struct SessionHandle *data = conn->data; |   struct SessionHandle *data = conn->data; | ||||||
|   int sockfd = conn->firstsocket; |   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 readfd; | ||||||
|   fd_set keepfd; |   fd_set keepfd; | ||||||
|  | #endif | ||||||
|   bool keepon = TRUE; |   bool keepon = TRUE; | ||||||
|   char *buf = data->state.buffer; |   char *buf = data->state.buffer; | ||||||
|   ssize_t nread; |   ssize_t nread; | ||||||
| @@ -1051,6 +1060,86 @@ CURLcode Curl_telnet(struct connectdata *conn) | |||||||
|   if(code) |   if(code) | ||||||
|     return 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_ZERO (&readfd);		/* clear it */ | ||||||
|   FD_SET (sockfd, &readfd); |   FD_SET (sockfd, &readfd); | ||||||
|   FD_SET (1, &readfd); |   FD_SET (1, &readfd); | ||||||
| @@ -1108,6 +1197,7 @@ CURLcode Curl_telnet(struct connectdata *conn) | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | #endif | ||||||
|   /* mark this as "no further transfer wanted" */ |   /* mark this as "no further transfer wanted" */ | ||||||
|   return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); |   return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); | ||||||
| } | } | ||||||
| @@ -1116,6 +1206,6 @@ CURLcode Curl_telnet(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -65,9 +65,14 @@ struct timeval Curl_tvnow (void) | |||||||
|  return now; |  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) | long Curl_tvlong (struct timeval t1) | ||||||
| @@ -79,6 +84,6 @@ long Curl_tvlong (struct timeval t1) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -43,7 +43,10 @@ struct timeval { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| struct timeval Curl_tvnow (); | 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); | long Curl_tvlong (struct timeval t1); | ||||||
|  |  | ||||||
| #endif | #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 |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -220,8 +220,6 @@ Transfer(struct connectdata *c_conn) | |||||||
|  |  | ||||||
|   hbufp = data->state.headerbuff; |   hbufp = data->state.headerbuff; | ||||||
|  |  | ||||||
|   myalarm (0);			/* switch off the alarm-style timeout */ |  | ||||||
|  |  | ||||||
|   now = Curl_tvnow(); |   now = Curl_tvnow(); | ||||||
|   start = now; |   start = now; | ||||||
|  |  | ||||||
| @@ -452,12 +450,14 @@ Transfer(struct connectdata *c_conn) | |||||||
|                 if (data->set.http_include_header) |                 if (data->set.http_include_header) | ||||||
|                   writetype |= CLIENTWRITE_BODY; |                   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); |                                         p - data->state.headerbuff); | ||||||
|                 if(urg) |                 if(urg) | ||||||
|                   return urg; |                   return urg; | ||||||
|  |  | ||||||
|                 data->info.header_size += p - data->state.headerbuff; |                 data->info.header_size += p - data->state.headerbuff; | ||||||
|  |                 conn->headerbytecount += p - data->state.headerbuff; | ||||||
|  |  | ||||||
|                 if(!header) { |                 if(!header) { | ||||||
|                   /* |                   /* | ||||||
| @@ -520,13 +520,8 @@ Transfer(struct connectdata *c_conn) | |||||||
|                   data->info.httpversion = httpversion; |                   data->info.httpversion = httpversion; | ||||||
|  |  | ||||||
|                   /* 404 -> URL not found! */ |                   /* 404 -> URL not found! */ | ||||||
|                   if ( |                   if (data->set.http_fail_on_error && | ||||||
|                       ( ((data->set.http_follow_location) && |                       (httpcode >= 400)) { | ||||||
|                          (httpcode >= 400)) |  | ||||||
|                         || |  | ||||||
|                         (!data->set.http_follow_location && |  | ||||||
|                          (httpcode >= 300))) |  | ||||||
|                       && (data->set.http_fail_on_error)) { |  | ||||||
|                     /* If we have been told to fail hard on HTTP-errors, |                     /* If we have been told to fail hard on HTTP-errors, | ||||||
|                        here is the check for that: */ |                        here is the check for that: */ | ||||||
|                     /* serious error, go home! */ |                     /* serious error, go home! */ | ||||||
| @@ -620,14 +615,14 @@ Transfer(struct connectdata *c_conn) | |||||||
|               } |               } | ||||||
|               else if(data->cookies && |               else if(data->cookies && | ||||||
|                       strnequal("Set-Cookie:", p, 11)) { |                       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, |               else if(strnequal("Last-Modified:", p, | ||||||
|                                 strlen("Last-Modified:")) && |                                 strlen("Last-Modified:")) && | ||||||
|                       (data->set.timecondition || data->set.get_filetime) ) { |                       (data->set.timecondition || data->set.get_filetime) ) { | ||||||
|                 time_t secs=time(NULL); |                 time_t secs=time(NULL); | ||||||
|                 timeofdoc = curl_getdate(p+strlen("Last-Modified:"), &secs); |                 timeofdoc = curl_getdate(p+strlen("Last-Modified:"), &secs); | ||||||
|                 if(data->set.get_filetime) |                 if(data->set.get_filetime>=0) | ||||||
|                   data->info.filetime = timeofdoc; |                   data->info.filetime = timeofdoc; | ||||||
|               } |               } | ||||||
|               else if ((httpcode >= 300 && httpcode < 400) && |               else if ((httpcode >= 300 && httpcode < 400) && | ||||||
| @@ -844,6 +839,12 @@ Transfer(struct connectdata *c_conn) | |||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       /* Update read/write counters */ | ||||||
|  |       if(conn->bytecountp) | ||||||
|  |         *conn->bytecountp = bytecount; /* read count */ | ||||||
|  |       if(conn->writebytecountp) | ||||||
|  |         *conn->writebytecountp = writebytecount; /* write count */ | ||||||
|  |  | ||||||
|       now = Curl_tvnow(); |       now = Curl_tvnow(); | ||||||
|       if(Curl_pgrsUpdate(conn)) |       if(Curl_pgrsUpdate(conn)) | ||||||
|         urg = CURLE_ABORTED_BY_CALLBACK; |         urg = CURLE_ABORTED_BY_CALLBACK; | ||||||
| @@ -861,11 +862,13 @@ Transfer(struct connectdata *c_conn) | |||||||
|         conn->upload_bufsize=(long)min(data->progress.ulspeed, BUFSIZE); |         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", | 	failf (data, "Operation timed out with %d out of %d bytes received", | ||||||
| 	       bytecount, conn->size); | 	       bytecount, conn->size); | ||||||
| 	return CURLE_OPERATION_TIMEOUTED; | 	return CURLE_OPERATION_TIMEOUTED; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -888,11 +891,6 @@ Transfer(struct connectdata *c_conn) | |||||||
|   if(Curl_pgrsUpdate(conn)) |   if(Curl_pgrsUpdate(conn)) | ||||||
|     return CURLE_ABORTED_BY_CALLBACK; |     return CURLE_ABORTED_BY_CALLBACK; | ||||||
|  |  | ||||||
|   if(conn->bytecountp) |  | ||||||
|     *conn->bytecountp = bytecount; /* read count */ |  | ||||||
|   if(conn->writebytecountp) |  | ||||||
|     *conn->writebytecountp = writebytecount; /* write count */ |  | ||||||
|  |  | ||||||
|   return CURLE_OK; |   return CURLE_OK; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -916,6 +914,7 @@ CURLcode Curl_perform(struct SessionHandle *data) | |||||||
|  |  | ||||||
|   data->set.followlocation=0; /* reset the location-follow counter */ |   data->set.followlocation=0; /* reset the location-follow counter */ | ||||||
|   data->state.this_is_a_follow = FALSE; /* reset this */ |   data->state.this_is_a_follow = FALSE; /* reset this */ | ||||||
|  |   data->state.errorbuf = FALSE; /* no error has occurred */ | ||||||
|  |  | ||||||
|   Curl_initinfo(data); /* reset session-specific information "variables" */ |   Curl_initinfo(data); /* reset session-specific information "variables" */ | ||||||
|  |  | ||||||
| @@ -926,7 +925,31 @@ CURLcode Curl_perform(struct SessionHandle *data) | |||||||
|     res = Curl_connect(data, &conn, port); |     res = Curl_connect(data, &conn, port); | ||||||
|     if(res == CURLE_OK) { |     if(res == CURLE_OK) { | ||||||
|       res = Curl_do(conn); |       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) { |       if(res == CURLE_OK) { | ||||||
|  |         CURLcode res2; /* just a local extra result container */ | ||||||
|  |  | ||||||
|         if(conn->protocol&PROT_FTPS) |         if(conn->protocol&PROT_FTPS) | ||||||
|           /* FTPS, disable ssl while transfering data */ |           /* FTPS, disable ssl while transfering data */ | ||||||
|           conn->ssl.use = FALSE; |           conn->ssl.use = FALSE; | ||||||
| @@ -935,15 +958,24 @@ CURLcode Curl_perform(struct SessionHandle *data) | |||||||
|           /* FTPS, enable ssl again after havving transferred data */ |           /* FTPS, enable ssl again after havving transferred data */ | ||||||
|           conn->ssl.use = TRUE; |           conn->ssl.use = TRUE; | ||||||
|  |  | ||||||
|         if(res == CURLE_OK) { |         if(res == CURLE_OK) | ||||||
|           /* |           /* | ||||||
|            * We must duplicate the new URL here as the connection data |            * We must duplicate the new URL here as the connection data | ||||||
|            * may be free()ed in the Curl_done() function. |            * may be free()ed in the Curl_done() function. | ||||||
|            */ |            */ | ||||||
|           newurl = conn->newurl?strdup(conn->newurl):NULL; |           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 */ |           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 |            *DANG* this is an RFC 2068 violation. The URL is supposed | ||||||
|            to be absolute and this doesn't seem to be that! |            to be absolute and this doesn't seem to be that! | ||||||
| @@ -1127,7 +1159,7 @@ CURLcode Curl_perform(struct SessionHandle *data) | |||||||
|   if(newurl) |   if(newurl) | ||||||
|     free(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) |   if(data->set.timeout || data->set.connecttimeout) | ||||||
|     myalarm(0); |     myalarm(0); | ||||||
|  |  | ||||||
| @@ -1166,6 +1198,6 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */ | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
							
								
								
									
										582
									
								
								lib/url.c
									
									
									
									
									
								
							
							
						
						
									
										582
									
								
								lib/url.c
									
									
									
									
									
								
							| @@ -107,6 +107,7 @@ | |||||||
| #include "file.h" | #include "file.h" | ||||||
| #include "ldap.h" | #include "ldap.h" | ||||||
| #include "url.h" | #include "url.h" | ||||||
|  | #include "connect.h" | ||||||
|  |  | ||||||
| #include <curl/types.h> | #include <curl/types.h> | ||||||
|  |  | ||||||
| @@ -153,17 +154,21 @@ CURLcode Curl_close(struct SessionHandle *data) | |||||||
|   Curl_SSL_Close_All(data); |   Curl_SSL_Close_All(data); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |   if(data->state.auth_host) | ||||||
|  |     free(data->state.auth_host); | ||||||
|  |  | ||||||
|   if(data->change.proxy_alloc) |   if(data->change.proxy_alloc) | ||||||
|     free(data->change.proxy); |     free(data->change.proxy); | ||||||
|  |  | ||||||
|   if(data->change.referer_alloc) |   if(data->change.referer_alloc) | ||||||
|     free(data->change.referer); |     free(data->change.referer); | ||||||
|  |  | ||||||
|   if(data->change.url_alloc) |   if(data->change.url_alloc) | ||||||
|     free(data->change.url); |     free(data->change.url); | ||||||
|  |  | ||||||
|   if(data->state.headerbuff) |   if(data->state.headerbuff) | ||||||
|     free(data->state.headerbuff); |     free(data->state.headerbuff); | ||||||
|  |  | ||||||
|  |  | ||||||
|   if(data->set.cookiejar) |   if(data->set.cookiejar) | ||||||
|     /* we have a "destination" for all the cookies to get dumped to */ |     /* we have a "destination" for all the cookies to get dumped to */ | ||||||
|     Curl_cookie_output(data->cookies, data->set.cookiejar); |     Curl_cookie_output(data->cookies, data->set.cookiejar); | ||||||
| @@ -201,84 +206,89 @@ CURLcode Curl_open(struct SessionHandle **curl) | |||||||
|  |  | ||||||
|   /* Very simple start-up: alloc the struct, init it with zeroes and return */ |   /* Very simple start-up: alloc the struct, init it with zeroes and return */ | ||||||
|   data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle)); |   data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle)); | ||||||
|   if(data) { |   if(!data) | ||||||
|     memset(data, 0, sizeof(struct SessionHandle)); |     /* this is a very serious error */ | ||||||
|  |     return CURLE_OUT_OF_MEMORY; | ||||||
|    |    | ||||||
|     /* We do some initial setup here, all those fields that can't be just 0 */ |   memset(data, 0, sizeof(struct SessionHandle)); | ||||||
|  |  | ||||||
|     data->state.headerbuff=(char*)malloc(HEADERSIZE); |   /* We do some initial setup here, all those fields that can't be just 0 */ | ||||||
|     if(!data->state.headerbuff) { |  | ||||||
|       free(data); /* free the memory again */ |  | ||||||
|       return CURLE_OUT_OF_MEMORY; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     data->state.headersize=HEADERSIZE; |   data->state.headerbuff=(char*)malloc(HEADERSIZE); | ||||||
|  |   if(!data->state.headerbuff) { | ||||||
|     data->set.out = stdout; /* default output to stdout */ |     free(data); /* free the memory again */ | ||||||
|     data->set.in  = stdin;  /* default input from stdin */ |     return CURLE_OUT_OF_MEMORY; | ||||||
|     data->set.err  = stderr;  /* default stderr to stderr */ |  | ||||||
|  |  | ||||||
|     /* use fwrite as default function to store output */ |  | ||||||
|     data->set.fwrite = (curl_write_callback)fwrite; |  | ||||||
|  |  | ||||||
|     /* use fread as default function to read input */ |  | ||||||
|     data->set.fread = (curl_read_callback)fread; |  | ||||||
|  |  | ||||||
|     /* set the default passwd function */ |  | ||||||
|     data->set.fpasswd = my_getpass; |  | ||||||
|  |  | ||||||
|     data->set.infilesize = -1; /* we don't know any size */ |  | ||||||
|  |  | ||||||
|     data->state.current_speed = -1; /* init to negative == impossible */ |  | ||||||
|  |  | ||||||
|     data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ |  | ||||||
|  |  | ||||||
|     /* make libcurl quiet by default: */ |  | ||||||
|     data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */ |  | ||||||
|     data->progress.flags |= PGRS_HIDE; |  | ||||||
|  |  | ||||||
|     /* Set the default size of the SSL session ID cache */ |  | ||||||
|     data->set.ssl.numsessions = 5; |  | ||||||
|  |  | ||||||
|     /* create an array with connection data struct pointers */ |  | ||||||
|     data->state.numconnects = 5; /* hard-coded right now */ |  | ||||||
|     data->state.connects = (struct connectdata **) |  | ||||||
|       malloc(sizeof(struct connectdata *) * data->state.numconnects); |  | ||||||
|  |  | ||||||
|     if(!data->state.connects) { |  | ||||||
|       free(data); |  | ||||||
|       return CURLE_OUT_OF_MEMORY; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     memset(data->state.connects, 0, |  | ||||||
|            sizeof(struct connectdata *)*data->state.numconnects); |  | ||||||
|  |  | ||||||
|     *curl = data; |  | ||||||
|  |  | ||||||
|     /************************************************************* |  | ||||||
|      * Set signal handler |  | ||||||
|      *************************************************************/ |  | ||||||
| #ifdef HAVE_SIGACTION |  | ||||||
|     sigaction(SIGALRM, NULL, &sigact); |  | ||||||
|     sigact.sa_handler = alarmfunc; |  | ||||||
| #ifdef SA_RESTART |  | ||||||
|     /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ |  | ||||||
|     sigact.sa_flags &= ~SA_RESTART; |  | ||||||
| #endif |  | ||||||
|     sigaction(SIGALRM, &sigact, NULL); |  | ||||||
| #else |  | ||||||
|     /* no sigaction(), revert to the much lamer signal() */ |  | ||||||
| #ifdef HAVE_SIGNAL |  | ||||||
|     signal(SIGALRM, alarmfunc); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|     return CURLE_OK; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* this is a very serious error */ |   data->state.headersize=HEADERSIZE; | ||||||
|   return CURLE_OUT_OF_MEMORY; |  | ||||||
|  |   data->set.out = stdout; /* default output to stdout */ | ||||||
|  |   data->set.in  = stdin;  /* default input from stdin */ | ||||||
|  |   data->set.err  = stderr;  /* default stderr to stderr */ | ||||||
|  |    | ||||||
|  |   /* use fwrite as default function to store output */ | ||||||
|  |   data->set.fwrite = (curl_write_callback)fwrite; | ||||||
|  |  | ||||||
|  |   /* use fread as default function to read input */ | ||||||
|  |   data->set.fread = (curl_read_callback)fread; | ||||||
|  |    | ||||||
|  |   /* set the default passwd function */ | ||||||
|  |   data->set.fpasswd = my_getpass; | ||||||
|  |  | ||||||
|  |   data->set.infilesize = -1; /* we don't know any size */ | ||||||
|  |  | ||||||
|  |   data->state.current_speed = -1; /* init to negative == impossible */ | ||||||
|  |  | ||||||
|  |   data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ | ||||||
|  |  | ||||||
|  |   /* make libcurl quiet by default: */ | ||||||
|  |   data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */ | ||||||
|  |   data->progress.flags |= PGRS_HIDE; | ||||||
|  |  | ||||||
|  |   /* Set the default size of the SSL session ID cache */ | ||||||
|  |   data->set.ssl.numsessions = 5; | ||||||
|  |  | ||||||
|  |   /* create an array with connection data struct pointers */ | ||||||
|  |   data->state.numconnects = 5; /* hard-coded right now */ | ||||||
|  |   data->state.connects = (struct connectdata **) | ||||||
|  |     malloc(sizeof(struct connectdata *) * data->state.numconnects); | ||||||
|  |    | ||||||
|  |   if(!data->state.connects) { | ||||||
|  |     free(data); | ||||||
|  |     return CURLE_OUT_OF_MEMORY; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   memset(data->state.connects, 0, | ||||||
|  |          sizeof(struct connectdata *)*data->state.numconnects); | ||||||
|  |  | ||||||
|  |   *curl = data; | ||||||
|  |  | ||||||
|  |   /************************************************************* | ||||||
|  |    * Set signal handler to catch SIGALRM | ||||||
|  |    *************************************************************/ | ||||||
|  | #ifdef HAVE_SIGACTION | ||||||
|  |   sigaction(SIGALRM, NULL, &sigact); | ||||||
|  |   sigact.sa_handler = alarmfunc; | ||||||
|  | #ifdef SA_RESTART | ||||||
|  |   /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ | ||||||
|  |   sigact.sa_flags &= ~SA_RESTART; | ||||||
|  | #endif | ||||||
|  |   sigaction(SIGALRM, &sigact, NULL); | ||||||
|  | #else | ||||||
|  |   /* no sigaction(), revert to the much lamer signal() */ | ||||||
|  | #ifdef HAVE_SIGNAL | ||||||
|  |   signal(SIGALRM, alarmfunc); | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   /************************************************************* | ||||||
|  |    * Tell signal handler to ignore SIGPIPE | ||||||
|  |    *************************************************************/ | ||||||
|  | #if defined(HAVE_SIGNAL) && defined(SIGPIPE) | ||||||
|  |   (void) signal(SIGPIPE, SIG_IGN); | ||||||
|  | #endif | ||||||
|  |    | ||||||
|  |   return CURLE_OK; | ||||||
| } | } | ||||||
|  |  | ||||||
| CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) | 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; |     data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; | ||||||
|     break; |     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: |   case CURLOPT_TRANSFERTEXT: | ||||||
|     /* |     /* | ||||||
|      * This option was previously named 'FTPASCII'. Renamed to work with |      * 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)) |     if(va_arg(param, long)) | ||||||
|       data->set.httpreq = HTTPREQ_PUT; |       data->set.httpreq = HTTPREQ_PUT; | ||||||
|     break; |     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: |   case CURLOPT_TIMECONDITION: | ||||||
|     /* |     /* | ||||||
|      * Set HTTP time condition. This must be one of the defines in the |      * 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. |      * 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; |     break; | ||||||
|   case CURLOPT_WRITEHEADER: |   case CURLOPT_WRITEHEADER: | ||||||
|     /* |     /* | ||||||
| @@ -863,7 +877,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) | |||||||
|  |  | ||||||
|   if(-1 != conn->connectindex) { |   if(-1 != conn->connectindex) { | ||||||
|     /* unlink ourselves! */ |     /* 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; |     conn->data->state.connects[conn->connectindex] = NULL; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -874,13 +888,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) | |||||||
|   if(conn->proto.generic) |   if(conn->proto.generic) | ||||||
|     free(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 */ |   if(conn->hostent_buf) /* host name info */ | ||||||
|     free(conn->hostent_buf); |     Curl_freeaddrinfo(conn->hostent_buf); | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   if(conn->newurl) |   if(conn->newurl) | ||||||
|     free(conn->newurl); |     free(conn->newurl); | ||||||
| @@ -987,10 +996,20 @@ ConnectionExists(struct SessionHandle *data, | |||||||
|         } |         } | ||||||
|         dead = SocketIsDead(check->firstsocket); |         dead = SocketIsDead(check->firstsocket); | ||||||
|         if(dead) { |         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); |           infof(data, "Connection %d seems to be dead!\n", i); | ||||||
|           Curl_disconnect(check); /* disconnect resources */ |           Curl_disconnect(check); /* disconnect resources */ | ||||||
|           data->state.connects[i]=NULL; /* nothing here */ |           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; |         *usethis = check; | ||||||
| @@ -1046,14 +1065,14 @@ ConnectionKillOne(struct SessionHandle *data) | |||||||
|        * Set higher score for the age passed since the connection |        * Set higher score for the age passed since the connection | ||||||
|        * was used. |        * was used. | ||||||
|        */ |        */ | ||||||
|       score = Curl_tvlong(now) - Curl_tvlong(conn->now); |       score = Curl_tvdiff(now, conn->now); | ||||||
|       break; |       break; | ||||||
|     case CURLCLOSEPOLICY_OLDEST: |     case CURLCLOSEPOLICY_OLDEST: | ||||||
|       /* |       /* | ||||||
|        * Set higher score for the age passed since the connection |        * Set higher score for the age passed since the connection | ||||||
|        * was created. |        * was created. | ||||||
|        */ |        */ | ||||||
|       score = Curl_tvlong(now) - Curl_tvlong(conn->created); |       score = Curl_tvdiff(now, conn->created); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1108,255 +1127,40 @@ ConnectionStore(struct SessionHandle *data, | |||||||
|   return i; |   return i; | ||||||
| } | } | ||||||
|  |  | ||||||
| static CURLcode ConnectPlease(struct SessionHandle *data, | static CURLcode ConnectPlease(struct connectdata *conn) | ||||||
|                               struct connectdata *conn) |  | ||||||
| { | { | ||||||
| #if defined(WIN32) |   CURLcode result; | ||||||
|   unsigned long nonblock = 0; |   Curl_ipconnect *addr; | ||||||
|   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*/ |  | ||||||
|  |  | ||||||
|   /************************************************************* |   /************************************************************* | ||||||
|    * Connect to server/proxy |    * 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 | #ifdef ENABLE_IPV6 | ||||||
|   conn->firstsocket = -1; |     conn->serv_addr = addr; | ||||||
|   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; |  | ||||||
|   } |  | ||||||
| #else | #else | ||||||
|   /* non-zero nonblock value sets socket as nonblocking under Win32 */ |     memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); | ||||||
| #if defined(WIN32) |     memcpy((char *)&(conn->serv_addr.sin_addr), | ||||||
|   FD_ZERO (&connectfd); |            (struct in_addr *)addr, sizeof(struct in_addr)); | ||||||
|   FD_SET(conn->firstsocket, &connectfd); |     conn->serv_addr.sin_family = conn->hostaddr->h_addrtype; | ||||||
|   if (conn->data->set.connecttimeout > 0) { |     conn->serv_addr.sin_port = htons(conn->port); | ||||||
|     nonblock = 1; | #endif | ||||||
|   } |   } | ||||||
|   ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); |  | ||||||
| #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, |                                  struct connectdata **in_connect, | ||||||
|                         bool allow_port) /* allow data->set.use_port ? */ |                                  bool allow_port) /* allow set.use_port? */ | ||||||
| { | { | ||||||
|   char *tmp; |   char *tmp; | ||||||
|   char *buf; |   char *buf; | ||||||
| @@ -1486,14 +1290,14 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     strcpy(conn->path, "/"); |     strcpy(conn->path, "/"); | ||||||
|  |  | ||||||
|     if (2 > sscanf(data->change.url, |     if (2 > sscanf(data->change.url, | ||||||
|                    "%64[^\n:]://%256[^\n/]%[^\n]", |                    "%64[^\n:]://%512[^\n/]%[^\n]", | ||||||
|                    conn->protostr, conn->gname, conn->path)) { |                    conn->protostr, conn->gname, conn->path)) { | ||||||
|        |        | ||||||
|       /* |       /* | ||||||
|        * The URL was badly formatted, let's try the browser-style _without_ |        * The URL was badly formatted, let's try the browser-style _without_ | ||||||
|        * protocol specified like 'http://'. |        * 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)) ) { |                      conn->gname, conn->path)) ) { | ||||||
|         /* |         /* | ||||||
|          * We couldn't even get this format. |          * We couldn't even get this format. | ||||||
| @@ -1700,12 +1504,12 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|   } /* if not using proxy */ |   } /* 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 ) { |   if(conn->protocol&PROT_MISSING) { | ||||||
|     /* We're guessing prefixes here and since we're told to use a proxy, we |     /* We're guessing prefixes here and if we're told to use a proxy or if | ||||||
|        need to add the protocol prefix to the URL string before we continue! |        we're gonna follow a Location: later or... then we need the protocol | ||||||
|        */ |        part added so that we have a valid URL. */ | ||||||
|     char *reurl; |     char *reurl; | ||||||
|  |  | ||||||
|     reurl = aprintf("%s://%s", conn->protostr, data->change.url); |     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 |    * Setup internals depending on protocol | ||||||
|    *************************************************************/ |    *************************************************************/ | ||||||
| @@ -1762,7 +1551,6 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     conn->protocol |= PROT_HTTP; |     conn->protocol |= PROT_HTTP; | ||||||
|     conn->curl_do = Curl_http; |     conn->curl_do = Curl_http; | ||||||
|     conn->curl_done = Curl_http_done; |     conn->curl_done = Curl_http_done; | ||||||
|     conn->curl_close = Curl_http_close; |  | ||||||
|   } |   } | ||||||
|   else if (strequal(conn->protostr, "HTTPS")) { |   else if (strequal(conn->protostr, "HTTPS")) { | ||||||
| #ifdef USE_SSLEAY | #ifdef USE_SSLEAY | ||||||
| @@ -1775,7 +1563,6 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     conn->curl_do = Curl_http; |     conn->curl_do = Curl_http; | ||||||
|     conn->curl_done = Curl_http_done; |     conn->curl_done = Curl_http_done; | ||||||
|     conn->curl_connect = Curl_http_connect; |     conn->curl_connect = Curl_http_connect; | ||||||
|     conn->curl_close = Curl_http_close; |  | ||||||
|  |  | ||||||
| #else /* USE_SSLEAY */ | #else /* USE_SSLEAY */ | ||||||
|     failf(data, LIBCURL_NAME |     failf(data, LIBCURL_NAME | ||||||
| @@ -1795,7 +1582,6 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     conn->protocol |= PROT_GOPHER; |     conn->protocol |= PROT_GOPHER; | ||||||
|     conn->curl_do = Curl_http; |     conn->curl_do = Curl_http; | ||||||
|     conn->curl_done = Curl_http_done; |     conn->curl_done = Curl_http_done; | ||||||
|     conn->curl_close = Curl_http_close; |  | ||||||
|   } |   } | ||||||
|   else if(strequal(conn->protostr, "FTP") || |   else if(strequal(conn->protostr, "FTP") || | ||||||
|           strequal(conn->protostr, "FTPS")) { |           strequal(conn->protostr, "FTPS")) { | ||||||
| @@ -1827,7 +1613,6 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|       } |       } | ||||||
|       conn->curl_do = Curl_http; |       conn->curl_do = Curl_http; | ||||||
|       conn->curl_done = Curl_http_done; |       conn->curl_done = Curl_http_done; | ||||||
|       conn->curl_close = Curl_http_close; |  | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       conn->curl_do = Curl_ftp; |       conn->curl_do = Curl_ftp; | ||||||
| @@ -1996,16 +1781,13 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|    * port number of various reasons. |    * port number of various reasons. | ||||||
|    * |    * | ||||||
|    * To be able to detect port number flawlessly, we must not confuse them |    * 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)) && |   if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && | ||||||
|      (']' == endbracket)) { |      (']' == endbracket)) { | ||||||
|     /* this is a IPv6-style specified IP-address */ |     /* This is a (IPv6-style) specified IP-address. We support _any_ | ||||||
| #ifndef ENABLE_IPV6 |        IP within brackets to be really generic. */ | ||||||
|     failf(data, "You haven't enabled IPv6 support"); |  | ||||||
|     return CURLE_URL_MALFORMAT; |  | ||||||
| #else |  | ||||||
|     conn->name++; /* pass the starting bracket */ |     conn->name++; /* pass the starting bracket */ | ||||||
|  |  | ||||||
|     tmp = strchr(conn->name, ']'); |     tmp = strchr(conn->name, ']'); | ||||||
| @@ -2014,7 +1796,6 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     tmp++; /* pass the ending bracket */ |     tmp++; /* pass the ending bracket */ | ||||||
|     if(':' != *tmp) |     if(':' != *tmp) | ||||||
|       tmp = NULL; /* no port number available */ |       tmp = NULL; /* no port number available */ | ||||||
| #endif |  | ||||||
|   } |   } | ||||||
|   else { |   else { | ||||||
|     /* traditional IPv4-style port-extracting */ |     /* traditional IPv4-style port-extracting */ | ||||||
| @@ -2101,7 +1882,6 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     conn = conn_temp;        /* use this connection from now on */ |     conn = conn_temp;        /* use this connection from now on */ | ||||||
|  |  | ||||||
|     /* we need these pointers if we speak over a proxy */ |     /* we need these pointers if we speak over a proxy */ | ||||||
|     conn->name = conn->gname; |  | ||||||
|     conn->hostname = old_conn->gname; |     conn->hostname = old_conn->gname; | ||||||
|  |  | ||||||
|     free(conn->path);    /* free the previously allocated path pointer */ |     free(conn->path);    /* free the previously allocated path pointer */ | ||||||
| @@ -2153,6 +1933,23 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|     ConnectionStore(data, conn); |     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 |    * 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 */ |     conn->port =  conn->remote_port; /* it is the same port */ | ||||||
|  |  | ||||||
|     /* Resolve target host right on */ |     /* Resolve target host right on */ | ||||||
|     if(!conn->hp) { |     if(!conn->hostaddr) { | ||||||
| #ifdef ENABLE_IPV6 |  | ||||||
|       /* it might already be set if reusing a connection */ |       /* it might already be set if reusing a connection */ | ||||||
|       conn->hp = Curl_getaddrinfo(data, conn->name, conn->port); |       conn->hostaddr = Curl_getaddrinfo(data, conn->name, conn->port, | ||||||
| #else |                                         &conn->hostent_buf); | ||||||
|       /* it might already be set if reusing a connection */ |  | ||||||
|       conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); |  | ||||||
| #endif |  | ||||||
|     } |     } | ||||||
|     if(!conn->hp) |     if(!conn->hostaddr) { | ||||||
|     { |  | ||||||
|       failf(data, "Couldn't resolve host '%s'", conn->name); |       failf(data, "Couldn't resolve host '%s'", conn->name); | ||||||
|       return CURLE_COULDNT_RESOLVE_HOST; |       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 |     /* This is a proxy that hasn't been resolved yet. It may be resolved | ||||||
|        if we're reusing an existing connection. */ |        if we're reusing an existing connection. */ | ||||||
|  |  | ||||||
|     /* resolve proxy */ |     /* resolve proxy */ | ||||||
| #ifdef ENABLE_IPV6 |     /* it might already be set if reusing a connection */ | ||||||
|       /* it might already be set if reusing a connection */ |     conn->hostaddr = Curl_getaddrinfo(data, conn->proxyhost, conn->port, | ||||||
|     conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port); |                                       &conn->hostent_buf); | ||||||
| #else |  | ||||||
|     conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf); |     if(!conn->hostaddr) { | ||||||
| #endif |  | ||||||
|     if(!conn->hp) { |  | ||||||
|       failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); |       failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); | ||||||
|       return CURLE_COULDNT_RESOLVE_PROXY; |       return CURLE_COULDNT_RESOLVE_PROXY; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   Curl_pgrsTime(data, TIMER_NAMELOOKUP); |   Curl_pgrsTime(data, TIMER_NAMELOOKUP); | ||||||
|  |   if(data->set.timeout || data->set.connecttimeout) | ||||||
|  |     /* switch off signal-based timeouts */ | ||||||
|  |     myalarm(0); | ||||||
|  |  | ||||||
|   /************************************************************* |   /************************************************************* | ||||||
|    * Proxy authentication |    * Proxy authentication | ||||||
| @@ -2227,7 +2020,7 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
|  |  | ||||||
|   if(-1 == conn->firstsocket) { |   if(-1 == conn->firstsocket) { | ||||||
|     /* Connect only if not already connected! */ |     /* Connect only if not already connected! */ | ||||||
|     result = ConnectPlease(data, conn); |     result = ConnectPlease(conn); | ||||||
|     if(CURLE_OK != result) |     if(CURLE_OK != result) | ||||||
|       return 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->now = Curl_tvnow(); /* time this *after* the connect is done */ | ||||||
|   conn->bytecount = 0; |   conn->bytecount = 0; | ||||||
|  |   conn->headerbytecount = 0; | ||||||
|    |    | ||||||
|   /* Figure out the ip-number and display the first host name it shows: */ |   /* Figure out the ip-number and display the first host name it shows: */ | ||||||
| #ifdef ENABLE_IPV6 | #ifdef ENABLE_IPV6 | ||||||
| @@ -2260,23 +2054,25 @@ static CURLcode Connect(struct SessionHandle *data, | |||||||
| #else | #else | ||||||
|     const int niflags = NI_NUMERICHOST; |     const int niflags = NI_NUMERICHOST; | ||||||
| #endif | #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, |     if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, | ||||||
| 	niflags)) { | 	niflags)) { | ||||||
|       snprintf(hbuf, sizeof(hbuf), "?"); |       snprintf(hbuf, sizeof(hbuf), "?"); | ||||||
|     } |     } | ||||||
|     if (ai->ai_canonname) { |     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 { |     } else { | ||||||
|       infof(data, "Connected to %s\n", hbuf); |       infof(data, "Connected to %s port %d\n", hbuf, conn->port); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| #else | #else | ||||||
|   { |   { | ||||||
|     struct in_addr in; |     struct in_addr in; | ||||||
|     (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr)); |     (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); | ||||||
|     infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in)); |     infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, | ||||||
|  |           inet_ntoa(in)); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -2303,7 +2099,7 @@ CURLcode Curl_connect(struct SessionHandle *data, | |||||||
|   struct connectdata *conn; |   struct connectdata *conn; | ||||||
|  |  | ||||||
|   /* call the stuff that needs to be called */ |   /* 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) { |   if(CURLE_OK != code) { | ||||||
|     /* We're not allowed to return failure with memory left allocated |     /* 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)) |      ((CURLE_OK == result) && conn->bits.close)) | ||||||
|     result = Curl_disconnect(conn); /* close the connection */ |     result = Curl_disconnect(conn); /* close the connection */ | ||||||
|   else |   else | ||||||
|     infof(data, "Connection (#%d) left alive\n", conn->connectindex); |     infof(data, "Connection #%d left intact\n", conn->connectindex); | ||||||
|  |  | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
| @@ -2374,6 +2170,6 @@ CURLcode Curl_do(struct connectdata *conn) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ | |||||||
| /* This file is for lib internal stuff */ | /* This file is for lib internal stuff */ | ||||||
|  |  | ||||||
| #include "setup.h" | #include "setup.h" | ||||||
|  | #include "hostip.h" | ||||||
|  |  | ||||||
| #define PORT_FTP 21 | #define PORT_FTP 21 | ||||||
| #define PORT_TELNET 23 | #define PORT_TELNET 23 | ||||||
| @@ -223,16 +224,16 @@ struct connectdata { | |||||||
| #define PROT_FILE    (1<<8) | #define PROT_FILE    (1<<8) | ||||||
| #define PROT_FTPS    (1<<9) | #define PROT_FTPS    (1<<9) | ||||||
|  |  | ||||||
| #ifdef ENABLE_IPV6 |   Curl_addrinfo *hostaddr; /* IP-protocol independent host info pointer list */ | ||||||
|   struct addrinfo *hp; /* host info pointer list */ |  | ||||||
|   struct addrinfo *ai; /* the particular host we use */ |  | ||||||
| #else |  | ||||||
|   char *hostent_buf; /* pointer to allocated memory for name info */ |   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; |   struct sockaddr_in serv_addr; | ||||||
| #endif | #endif | ||||||
|   char protostr[64];  /* store the protocol string in this buffer */ |   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 *name;      /* host name pointer to fool around with */ | ||||||
|   char *path;      /* allocated buffer to store the URL's path part in */ |   char *path;      /* allocated buffer to store the URL's path part in */ | ||||||
|   char *hostname;  /* hostname to connect, as parsed from url */ |   char *hostname;  /* hostname to connect, as parsed from url */ | ||||||
| @@ -241,6 +242,7 @@ struct connectdata { | |||||||
|                                  not the proxy port! */ |                                  not the proxy port! */ | ||||||
|   char *ppath; |   char *ppath; | ||||||
|   long bytecount; |   long bytecount; | ||||||
|  |   long headerbytecount;  /* only count received headers */ | ||||||
|  |  | ||||||
|   char *range; /* range, if used. See README for detailed specification on |   char *range; /* range, if used. See README for detailed specification on | ||||||
|                   this syntax. */ |                   this syntax. */ | ||||||
| @@ -351,8 +353,8 @@ struct connectdata { | |||||||
| struct PureInfo { | struct PureInfo { | ||||||
|   int httpcode; |   int httpcode; | ||||||
|   int httpversion; |   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 */ |                     the time was unretrievable */ | ||||||
|   long header_size;  /* size of read header(s) in bytes */ |   long header_size;  /* size of read header(s) in bytes */ | ||||||
|   long request_size; /* the amount of bytes sent in the request(s) */ |   long request_size; /* the amount of bytes sent in the request(s) */ | ||||||
| }; | }; | ||||||
| @@ -371,7 +373,9 @@ struct Progress { | |||||||
|   bool callback;  /* set when progress callback is used */ |   bool callback;  /* set when progress callback is used */ | ||||||
|   int width; /* screen width at download start */ |   int width; /* screen width at download start */ | ||||||
|   int flags; /* see progress.h */ |   int flags; /* see progress.h */ | ||||||
|   double timespent; |  | ||||||
|  |   long timespent; | ||||||
|  |  | ||||||
|   double dlspeed; |   double dlspeed; | ||||||
|   double ulspeed; |   double ulspeed; | ||||||
|  |  | ||||||
| @@ -381,9 +385,10 @@ struct Progress { | |||||||
|  |  | ||||||
|   struct timeval start; |   struct timeval start; | ||||||
|   struct timeval t_startsingle; |   struct timeval t_startsingle; | ||||||
| #define CURR_TIME 5 | #define CURR_TIME (5+1) /* 6 entries for 5 seconds */ | ||||||
|  |  | ||||||
|   double speeder[ CURR_TIME ]; |   double speeder[ CURR_TIME ]; | ||||||
|  |   struct timeval speeder_time[ CURR_TIME ]; | ||||||
|   int speeder_c; |   int speeder_c; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -441,6 +446,9 @@ struct UrlState { | |||||||
|   long sessionage;                  /* number of the most recent session */ |   long sessionage;                  /* number of the most recent session */ | ||||||
|  |  | ||||||
|   char scratch[BUFSIZE*2]; /* huge buffer when doing upload CRLF replacing */ |   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 *quote;     /* before the transfer */ | ||||||
|   struct curl_slist *postquote; /* after the transfer */ |   struct curl_slist *postquote; /* after the transfer */ | ||||||
|   struct curl_slist *telnet_options; /* linked list of telnet options */ |   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 */ |   time_t timevalue;       /* what time to compare with */ | ||||||
|   curl_closepolicy closepolicy; /* connection cache close concept */ |   curl_closepolicy closepolicy; /* connection cache close concept */ | ||||||
|   Curl_HttpReq httpreq;   /* what kind of HTTP request (if any) is this */ |   Curl_HttpReq httpreq;   /* what kind of HTTP request (if any) is this */ | ||||||
|   char *customrequest;    /* HTTP/FTP request to use */ |   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 |   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 |                     * to which to send the authorization data to, and no other | ||||||
|                     * host (which location-following otherwise could lead to) |                     * host (which location-following otherwise could lead to) | ||||||
|   | |||||||
| @@ -108,6 +108,6 @@ char *curl_version(void) | |||||||
|  * local variables: |  * local variables: | ||||||
|  * eval: (load-file "../curl-mode.el") |  * eval: (load-file "../curl-mode.el") | ||||||
|  * end: |  * end: | ||||||
|  * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker |  * vim600: fdm=marker | ||||||
|  * vim<600: et sw=2 ts=2 sts=2 tw=78 |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  */ |  */ | ||||||
|   | |||||||
							
								
								
									
										68
									
								
								ltmain.sh
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								ltmain.sh
									
									
									
									
									
								
							| @@ -55,8 +55,8 @@ modename="$progname" | |||||||
| # Constants. | # Constants. | ||||||
| PROGRAM=ltmain.sh | PROGRAM=ltmain.sh | ||||||
| PACKAGE=libtool | PACKAGE=libtool | ||||||
| VERSION=1.4.1 | VERSION=1.4.2 | ||||||
| TIMESTAMP=" (1.922.2.34 2001/09/03 01:22:13)" | TIMESTAMP=" (1.922.2.54 2001/09/11 03:33:37)" | ||||||
|  |  | ||||||
| default_mode= | default_mode= | ||||||
| help="Try \`$progname --help' for more information." | help="Try \`$progname --help' for more information." | ||||||
| @@ -84,6 +84,9 @@ if test "${LANG+set}" = set; then | |||||||
|   save_LANG="$LANG"; LANG=C; export LANG |   save_LANG="$LANG"; LANG=C; export LANG | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | # Make sure IFS has a sensible default | ||||||
|  | : ${IFS=" 	"} | ||||||
|  |  | ||||||
| if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then | 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 "$modename: not configured to build any kind of library" 1>&2 | ||||||
|   echo "Fatal configuration error.  See the $PACKAGE docs for more information." 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,*) |       -Wc,*) | ||||||
| 	args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` | 	args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` | ||||||
| 	lastarg= | 	lastarg= | ||||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=',' | 	save_ifs="$IFS"; IFS=',' | ||||||
| 	for arg in $args; do | 	for arg in $args; do | ||||||
| 	  IFS="$save_ifs" | 	  IFS="$save_ifs" | ||||||
|  |  | ||||||
| @@ -1045,8 +1048,7 @@ compiler." | |||||||
| 	    test "X$arg" = "X-lc" && continue | 	    test "X$arg" = "X-lc" && continue | ||||||
| 	    ;; | 	    ;; | ||||||
| 	  esac | 	  esac | ||||||
| 	 fi | 	 elif test "X$arg" = "X-lc_r"; then | ||||||
| 	 if test "X$arg" = "X-lc_r"; then |  | ||||||
| 	  case $host in | 	  case $host in | ||||||
| 	  *-*-openbsd*) | 	  *-*-openbsd*) | ||||||
| 	    # Do not include libc_r directly, use -pthread flag. | 	    # Do not include libc_r directly, use -pthread flag. | ||||||
| @@ -1143,7 +1145,7 @@ compiler." | |||||||
|       -Wc,*) |       -Wc,*) | ||||||
| 	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` | 	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` | ||||||
| 	arg= | 	arg= | ||||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=',' | 	save_ifs="$IFS"; IFS=',' | ||||||
| 	for flag in $args; do | 	for flag in $args; do | ||||||
| 	  IFS="$save_ifs" | 	  IFS="$save_ifs" | ||||||
| 	  case $flag in | 	  case $flag in | ||||||
| @@ -1161,7 +1163,7 @@ compiler." | |||||||
|       -Wl,*) |       -Wl,*) | ||||||
| 	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` | 	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` | ||||||
| 	arg= | 	arg= | ||||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=',' | 	save_ifs="$IFS"; IFS=',' | ||||||
| 	for flag in $args; do | 	for flag in $args; do | ||||||
| 	  IFS="$save_ifs" | 	  IFS="$save_ifs" | ||||||
| 	  case $flag in | 	  case $flag in | ||||||
| @@ -1771,7 +1773,7 @@ compiler." | |||||||
| 	    if test -f "$output_objdir/$soname-def"; then : | 	    if test -f "$output_objdir/$soname-def"; then : | ||||||
| 	    else | 	    else | ||||||
| 	      $show "extracting exported symbol list from \`$soname'" | 	      $show "extracting exported symbol list from \`$soname'" | ||||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	      save_ifs="$IFS"; IFS='~' | ||||||
| 	      eval cmds=\"$extract_expsyms_cmds\" | 	      eval cmds=\"$extract_expsyms_cmds\" | ||||||
| 	      for cmd in $cmds; do | 	      for cmd in $cmds; do | ||||||
| 		IFS="$save_ifs" | 		IFS="$save_ifs" | ||||||
| @@ -1784,7 +1786,7 @@ compiler." | |||||||
| 	    # Create $newlib | 	    # Create $newlib | ||||||
| 	    if test -f "$output_objdir/$newlib"; then :; else | 	    if test -f "$output_objdir/$newlib"; then :; else | ||||||
| 	      $show "generating import library for \`$soname'" | 	      $show "generating import library for \`$soname'" | ||||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	      save_ifs="$IFS"; IFS='~' | ||||||
| 	      eval cmds=\"$old_archive_from_expsyms_cmds\" | 	      eval cmds=\"$old_archive_from_expsyms_cmds\" | ||||||
| 	      for cmd in $cmds; do | 	      for cmd in $cmds; do | ||||||
| 		IFS="$save_ifs" | 		IFS="$save_ifs" | ||||||
| @@ -2196,7 +2198,7 @@ compiler." | |||||||
|       else |       else | ||||||
|  |  | ||||||
| 	# Parse the version information argument. | 	# Parse the version information argument. | ||||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=':' | 	save_ifs="$IFS"; IFS=':' | ||||||
| 	set dummy $vinfo 0 0 0 | 	set dummy $vinfo 0 0 0 | ||||||
| 	IFS="$save_ifs" | 	IFS="$save_ifs" | ||||||
|  |  | ||||||
| @@ -2818,7 +2820,7 @@ EOF | |||||||
| 	    export_symbols="$output_objdir/$libname.exp" | 	    export_symbols="$output_objdir/$libname.exp" | ||||||
| 	    $run $rm $export_symbols | 	    $run $rm $export_symbols | ||||||
| 	    eval cmds=\"$export_symbols_cmds\" | 	    eval cmds=\"$export_symbols_cmds\" | ||||||
| 	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	    save_ifs="$IFS"; IFS='~' | ||||||
| 	    for cmd in $cmds; do | 	    for cmd in $cmds; do | ||||||
| 	      IFS="$save_ifs" | 	      IFS="$save_ifs" | ||||||
| 	      $show "$cmd" | 	      $show "$cmd" | ||||||
| @@ -2894,7 +2896,7 @@ EOF | |||||||
| 	else | 	else | ||||||
| 	  eval cmds=\"$archive_cmds\" | 	  eval cmds=\"$archive_cmds\" | ||||||
| 	fi | 	fi | ||||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	save_ifs="$IFS"; IFS='~' | ||||||
| 	for cmd in $cmds; do | 	for cmd in $cmds; do | ||||||
| 	  IFS="$save_ifs" | 	  IFS="$save_ifs" | ||||||
| 	  $show "$cmd" | 	  $show "$cmd" | ||||||
| @@ -3022,7 +3024,7 @@ EOF | |||||||
|  |  | ||||||
|       output="$obj" |       output="$obj" | ||||||
|       eval cmds=\"$reload_cmds\" |       eval cmds=\"$reload_cmds\" | ||||||
|       IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' |       save_ifs="$IFS"; IFS='~' | ||||||
|       for cmd in $cmds; do |       for cmd in $cmds; do | ||||||
| 	IFS="$save_ifs" | 	IFS="$save_ifs" | ||||||
| 	$show "$cmd" | 	$show "$cmd" | ||||||
| @@ -3058,7 +3060,7 @@ EOF | |||||||
| 	reload_objs="$libobjs $reload_conv_objs" | 	reload_objs="$libobjs $reload_conv_objs" | ||||||
| 	output="$libobj" | 	output="$libobj" | ||||||
| 	eval cmds=\"$reload_cmds\" | 	eval cmds=\"$reload_cmds\" | ||||||
| 	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	save_ifs="$IFS"; IFS='~' | ||||||
| 	for cmd in $cmds; do | 	for cmd in $cmds; do | ||||||
| 	  IFS="$save_ifs" | 	  IFS="$save_ifs" | ||||||
| 	  $show "$cmd" | 	  $show "$cmd" | ||||||
| @@ -3823,7 +3825,7 @@ fi\ | |||||||
|  |  | ||||||
| 	eval cmds=\"$old_archive_cmds\" | 	eval cmds=\"$old_archive_cmds\" | ||||||
|       fi |       fi | ||||||
|       IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' |       save_ifs="$IFS"; IFS='~' | ||||||
|       for cmd in $cmds; do |       for cmd in $cmds; do | ||||||
| 	IFS="$save_ifs" | 	IFS="$save_ifs" | ||||||
| 	$show "$cmd" | 	$show "$cmd" | ||||||
| @@ -4198,7 +4200,7 @@ relink_command=\"$relink_command\"" | |||||||
| 	  # Do each command in the postinstall commands. | 	  # Do each command in the postinstall commands. | ||||||
| 	  lib="$destdir/$realname" | 	  lib="$destdir/$realname" | ||||||
| 	  eval cmds=\"$postinstall_cmds\" | 	  eval cmds=\"$postinstall_cmds\" | ||||||
| 	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	  save_ifs="$IFS"; IFS='~' | ||||||
| 	  for cmd in $cmds; do | 	  for cmd in $cmds; do | ||||||
| 	    IFS="$save_ifs" | 	    IFS="$save_ifs" | ||||||
| 	    $show "$cmd" | 	    $show "$cmd" | ||||||
| @@ -4271,19 +4273,31 @@ relink_command=\"$relink_command\"" | |||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| 	# Do a test to see if this is really a libtool program. | 	# 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= | 	  notinst_deplibs= | ||||||
| 	  relink_command= | 	  relink_command= | ||||||
|  |  | ||||||
| 	  # If there is no directory component, then add one. | 	  # If there is no directory component, then add one. | ||||||
| 	  case $file in | 	  case $file in | ||||||
| 	  */* | *\\*) . $file ;; | 	  #*/* | *\\*) . $file ;; | ||||||
| 	  *) . ./$file ;; | 	  #*) . ./$file ;; | ||||||
|  | 	  */* | *\\*) . $wrapper ;; | ||||||
|  | 	  *) . ./$wrapper ;; | ||||||
| 	  esac | 	  esac | ||||||
|  |  | ||||||
| 	  # Check the variables that should have been set. | 	  # Check the variables that should have been set. | ||||||
| 	  if test -z "$notinst_deplibs"; then | 	  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 | 	    exit 1 | ||||||
| 	  fi | 	  fi | ||||||
|  |  | ||||||
| @@ -4308,8 +4322,10 @@ relink_command=\"$relink_command\"" | |||||||
| 	  relink_command= | 	  relink_command= | ||||||
| 	  # If there is no directory component, then add one. | 	  # If there is no directory component, then add one. | ||||||
| 	  case $file in | 	  case $file in | ||||||
| 	  */* | *\\*) . $file ;; | 	  #*/* | *\\*) . $file ;; | ||||||
| 	  *) . ./$file ;; | 	  #*) . ./$file ;; | ||||||
|  | 	  */* | *\\*) . $wrapper ;; | ||||||
|  | 	  *) . ./$wrapper ;; | ||||||
| 	  esac | 	  esac | ||||||
|  |  | ||||||
| 	  outputname= | 	  outputname= | ||||||
| @@ -4385,7 +4401,7 @@ relink_command=\"$relink_command\"" | |||||||
|  |  | ||||||
|       # Do each command in the postinstall commands. |       # Do each command in the postinstall commands. | ||||||
|       eval cmds=\"$old_postinstall_cmds\" |       eval cmds=\"$old_postinstall_cmds\" | ||||||
|       IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' |       save_ifs="$IFS"; IFS='~' | ||||||
|       for cmd in $cmds; do |       for cmd in $cmds; do | ||||||
| 	IFS="$save_ifs" | 	IFS="$save_ifs" | ||||||
| 	$show "$cmd" | 	$show "$cmd" | ||||||
| @@ -4423,7 +4439,7 @@ relink_command=\"$relink_command\"" | |||||||
| 	if test -n "$finish_cmds"; then | 	if test -n "$finish_cmds"; then | ||||||
| 	  # Do each command in the finish commands. | 	  # Do each command in the finish commands. | ||||||
| 	  eval cmds=\"$finish_cmds\" | 	  eval cmds=\"$finish_cmds\" | ||||||
| 	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	  save_ifs="$IFS"; IFS='~' | ||||||
| 	  for cmd in $cmds; do | 	  for cmd in $cmds; do | ||||||
| 	    IFS="$save_ifs" | 	    IFS="$save_ifs" | ||||||
| 	    $show "$cmd" | 	    $show "$cmd" | ||||||
| @@ -4699,7 +4715,7 @@ relink_command=\"$relink_command\"" | |||||||
| 	    if test -n "$library_names"; then | 	    if test -n "$library_names"; then | ||||||
| 	      # Do each command in the postuninstall commands. | 	      # Do each command in the postuninstall commands. | ||||||
| 	      eval cmds=\"$postuninstall_cmds\" | 	      eval cmds=\"$postuninstall_cmds\" | ||||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	      save_ifs="$IFS"; IFS='~' | ||||||
| 	      for cmd in $cmds; do | 	      for cmd in $cmds; do | ||||||
| 		IFS="$save_ifs" | 		IFS="$save_ifs" | ||||||
| 		$show "$cmd" | 		$show "$cmd" | ||||||
| @@ -4714,7 +4730,7 @@ relink_command=\"$relink_command\"" | |||||||
| 	    if test -n "$old_library"; then | 	    if test -n "$old_library"; then | ||||||
| 	      # Do each command in the old_postuninstall commands. | 	      # Do each command in the old_postuninstall commands. | ||||||
| 	      eval cmds=\"$old_postuninstall_cmds\" | 	      eval cmds=\"$old_postuninstall_cmds\" | ||||||
| 	      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~' | 	      save_ifs="$IFS"; IFS='~' | ||||||
| 	      for cmd in $cmds; do | 	      for cmd in $cmds; do | ||||||
| 		IFS="$save_ifs" | 		IFS="$save_ifs" | ||||||
| 		$show "$cmd" | 		$show "$cmd" | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								maketgz
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								maketgz
									
									
									
									
									
								
							| @@ -61,7 +61,8 @@ findprog() | |||||||
| # Enforce a rerun of configure (updates the VERSION) | # 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!" |   echo "- Could not find or run automake, I hope you know what you're doing!" | ||||||
| else | else | ||||||
|   echo "Runs automake --include-deps" |   echo "Runs automake --include-deps" | ||||||
|   automake --include-deps Makefile |   automake --include-deps Makefile >/dev/null | ||||||
| fi | 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 | 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--; |                 $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 { |     else { | ||||||
|         print "Not recognized prefix line: $line\n"; |         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) { | if($verbose) { | ||||||
|     print "Mallocs: $mallocs\n", |     print "Mallocs: $mallocs\n", | ||||||
|     "Reallocs: $reallocs\n", |     "Reallocs: $reallocs\n", | ||||||
|   | |||||||
| @@ -1 +1,3 @@ | |||||||
|  | SUBDIRS = cygwin | ||||||
|  |  | ||||||
| EXTRA_DIST = README | 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