Compare commits
	
		
			146 Commits
		
	
	
		
			curl_7_6-p
			...
			curl-7_7_a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | cf8704ccdf | ||
|   | 5543c2f11f | ||
|   | 90ac37a683 | ||
|   | dd893fd8a4 | ||
|   | 834f079918 | ||
|   | 2665c763df | ||
|   | d1cfbd51b5 | ||
|   | a3ba6b7a6a | ||
|   | 415d2e7cb7 | ||
|   | af4451ec26 | ||
|   | 7c6562683a | ||
|   | b6fa2f882c | ||
|   | b6c5da337a | ||
|   | 9bc24e4876 | ||
|   | 4af55809e4 | ||
|   | 9c63fcf210 | ||
|   | 1f17fb5f89 | ||
|   | 584dbffe60 | ||
|   | 1c6f6f6972 | ||
|   | da06a6e7e3 | ||
|   | 46e0937263 | ||
|   | a1d6ad2610 | ||
|   | 5f3d63ed5b | ||
|   | 63b5748eb6 | ||
|   | e2590430c5 | ||
|   | ada9bc2b24 | ||
|   | 43da41e73e | ||
|   | 720fa45b56 | ||
|   | 7de874c438 | ||
|   | 2078c1a01a | ||
|   | f7a8909372 | ||
|   | 250df30e64 | ||
|   | b887cf7521 | ||
|   | 630e932091 | ||
|   | cdabd67aa9 | ||
|   | 42e4f9d776 | ||
|   | c111033595 | ||
|   | 26d1aaccdf | ||
|   | ce95d2020f | ||
|   | 948c3b3aa9 | ||
|   | a140e5311d | ||
|   | 7686ac3f2c | ||
|   | 54778134e4 | ||
|   | c59baa06f0 | ||
|   | c107303ade | ||
|   | 21b05afc99 | ||
|   | eebcf7d4f5 | ||
|   | 8d169dfadd | ||
|   | b12e334d83 | ||
|   | 7e36c4437e | ||
|   | 3c7a80a275 | ||
|   | 61e2a8108b | ||
|   | abb14de7e0 | ||
|   | ccd57e58f6 | ||
|   | 58d70db92e | ||
|   | 09f6fc22ed | ||
|   | 833ce37cb9 | ||
|   | 07e7018564 | ||
|   | db70cd28b3 | ||
|   | f6e2bfd464 | ||
|   | 1ae5dab8fb | ||
|   | c6355e6a43 | ||
|   | 7d26eb61fe | ||
|   | 8613ce377f | ||
|   | d6b94488a1 | ||
|   | 5d7b32d09f | ||
|   | ed16d30ea8 | ||
|   | 6f7c70fbbc | ||
|   | 9ab5d30e3b | ||
|   | 3b44a3df76 | ||
|   | 572c29a4a3 | ||
|   | 9464c5430d | ||
|   | a14aaaf23f | ||
|   | c41c5a0ef2 | ||
|   | c0c0283356 | ||
|   | 1bcd3e601a | ||
|   | e721f85c83 | ||
|   | 7015c61b86 | ||
|   | 30ec0af109 | ||
|   | f585b66af7 | ||
|   | 1b77c18430 | ||
|   | bd0bd35771 | ||
|   | 368e3526ea | ||
|   | 1bbe407a4d | ||
|   | 513bc44421 | ||
|   | 4cc76d1576 | ||
|   | 6dc5c6ffc7 | ||
|   | c69c79dd04 | ||
|   | 7fca24b14b | ||
|   | 2fa0d3dd5f | ||
|   | 3a8210c975 | ||
|   | d69302202d | ||
|   | 227662d2ed | ||
|   | 3cb3d43913 | ||
|   | c8a546c941 | ||
|   | 62fec1d28d | ||
|   | ac98c73b04 | ||
|   | a145654394 | ||
|   | e8382ba290 | ||
|   | fcb347d124 | ||
|   | c331ef02f9 | ||
|   | 3a3f632bf0 | ||
|   | 68d7b6f871 | ||
|   | c43a9d9068 | ||
|   | 64e80091db | ||
|   | 4f255ffbeb | ||
|   | 80d75b0eaf | ||
|   | 808c4020e6 | ||
|   | 149d6363b3 | ||
|   | 30eab8ca51 | ||
|   | e49a82b06c | ||
|   | 45fdb48189 | ||
|   | 3fcc9677c4 | ||
|   | 1552bd9c8c | ||
|   | 939c0c5521 | ||
|   | f0b9aefd2e | ||
|   | 11f3c51e8f | ||
|   | 1a329b98a3 | ||
|   | 29bcba9a90 | ||
|   | 1716dbb68a | ||
|   | 16ecfcf62c | ||
|   | 8bafc3692d | ||
|   | 8a75120568 | ||
|   | 3d96ee7423 | ||
|   | b3dbdfa306 | ||
|   | 25bad589ba | ||
|   | 0b6cd75004 | ||
|   | 7872cc131a | ||
|   | 210aa4371c | ||
|   | 6f438bc8fb | ||
|   | 65840f1fd1 | ||
|   | 5fc492e5c6 | ||
|   | abcd1e7d5a | ||
|   | 6429c378a2 | ||
|   | d830f10417 | ||
|   | 3d6fcbf97b | ||
|   | 609be218c2 | ||
|   | 41084e57ca | ||
|   | 9afab85105 | ||
|   | 7822233964 | ||
|   | 022315089b | ||
|   | faa5c14aee | ||
|   | 3dd886955b | ||
|   | c2dbf21459 | ||
|   | 133eb220b9 | ||
|   | c5796d9e39 | 
							
								
								
									
										259
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										259
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -6,6 +6,265 @@ | ||||
|  | ||||
|                                History of Changes | ||||
|  | ||||
| ** curl 7.7 DOES NOT currently WORK. ** | ||||
|  | ||||
| Daniel (4 March 2001) | ||||
| - Now, there's even a basic check that a re-used connection is still alive | ||||
|   before it is assumed so. A few first tests have proven that libcurl will | ||||
|   then re-connect instead of re-use the dead connection! | ||||
|  | ||||
| Daniel (2 March 2001) | ||||
| - Now they work intermixed as well. Major coolness! | ||||
|  | ||||
| - More fiddling around, my 'tiny' client I have for testing purposes now has | ||||
|   proved to download both FTP and HTTP with persistant connections. They do | ||||
|   not work intermixed yet though. | ||||
|  | ||||
| Daniel (1 March 2001) | ||||
| - Wilfredo Sanchez pointed out a minor spelling mistake in a man page and that | ||||
|   curl_slist_append() should take a const char * as second argument. It does | ||||
|   now. | ||||
|  | ||||
| Daniel (22 February 2001) | ||||
| - The persistant connections start to look good for HTTP. On a subsequent | ||||
|   request, it seems that libcurl now can pick an already existing connection | ||||
|   if a suitable one exists, or it opens a new one. | ||||
|  | ||||
| - Douglas R. Horner mailed me corrections to the curl_formparse() man page | ||||
|   that I applied. | ||||
|  | ||||
| Daniel (20 February 2001) | ||||
| - Added the docs/examples/win32sockets.c file for our windows friends. | ||||
|  | ||||
| - Linus Nielsen Feltzing provided brand new TELNET functionality and | ||||
|   improvements: | ||||
|  | ||||
|   * Negotiation is now passive. Curl does not negotiate until the peer does. | ||||
|   * Possibility to set negotiation options on the command line, currently only | ||||
|     XDISPLOC, TTYPE and NEW_ENVIRON (called NEW_ENV). | ||||
|   * Now sends the USER environment variable if the -u switch is used. | ||||
|   * Use -t to set telnet options (Linus even updated the man page, awesome!) | ||||
|  | ||||
| - Haven't done this big changes to curl for a while. Moved around a lot of | ||||
|   struct fields and stuff to make multiple connections get connection specific | ||||
|   data in separate structs so that they can co-exist in a nice way. See the | ||||
|   mailing lists for discussions around how this is gonna be implemented. Docs | ||||
|   and more will follow. | ||||
|  | ||||
|   Studied the HTTP RFC to find out better how persistant connections should | ||||
|   work. Seems cool enough. | ||||
|  | ||||
| Daniel (19 February 2001) | ||||
| - Bob Schader brought me two files that help set up a MS VC++ libcurl project | ||||
|   easier. He also provided me with an up-to-date libcurl.def file. | ||||
|  | ||||
| - I moved a bunch of prototypes from the public <curl/curl.h> file to the | ||||
|   library private urldata.h. This is because of the upcoming changes. The | ||||
|   low level interface is no longer being planned to become reality. | ||||
|  | ||||
| Daniel (15 February 2001) | ||||
| - CURLOPT_POST is not required anymore. Just setting the POST string with | ||||
|   CURLOPT_POSTFIELDS will switch on the HTTP POST. Most other things in | ||||
|   libcurl already works this way, i.e they require only the parameter to | ||||
|   switch on a feature so I think this works well with the rest. Setting a NULL | ||||
|   string switches off the POST again. | ||||
|  | ||||
| - Excellent suggestions from Rich Gray, Rick Jones, Johan Nilsson and Bjorn | ||||
|   Reese helped me define a way how to incorporate persistant connections into | ||||
|   libcurl in a very smooth way. If done right, no change may have to be made | ||||
|   to older programs and they will just start using persistant connections when | ||||
|   applicable! | ||||
|  | ||||
| Daniel (13 February 2001) | ||||
| - Changed the word 'timeouted' to 'timed out' in two different error messages. | ||||
|   Suggested by Larry Fahnoe. | ||||
|  | ||||
| Version 7.6.1 | ||||
|  | ||||
| Daniel (9 February 2001) | ||||
| - Frank Reid and Cain Hopwood provided information and research around a HTTPS | ||||
|   PUT/upload problem we seem to have. No solution found yet. | ||||
|  | ||||
| Daniel (8 February 2001) | ||||
| - An interesting discussion is how to specify an empty password without having | ||||
|   curl ask for it interactively? The current implmentation takes an empty | ||||
|   password as a request for a password prompt. However, I still want to | ||||
|   support a blank user field. Thus, today if you enter "-u :" (without user | ||||
|   and password) curl will prompt for the password. Tricky. How would you | ||||
|   specify you want the prompt otherwise? | ||||
|  | ||||
| - Made the netrc parse result possible to use for other protocols than FTP and | ||||
|   HTTP (such as the upcoming TELNET fixes). | ||||
|  | ||||
| - The previously mentioned "MSVC++ problems" turned out to be a non-issue. | ||||
|  | ||||
| - Added a HTTP file upload code example in the docs/examples/ section on | ||||
|   request. | ||||
|  | ||||
| - Adjusted the FTP response fix slightly. | ||||
|  | ||||
| Version 7.6.1-pre3 | ||||
|  | ||||
| Daniel (7 February 2001) | ||||
| - SM found a flaw in the response reading function for FTP that could make | ||||
|   libcurl not get out of the loop properly when it should, if libcurl got -1 | ||||
|   returned when reading the socket. | ||||
|  | ||||
| - I found a similar mistake in http.c when using a proxy and reading the | ||||
|   results from the proxy connection. | ||||
|  | ||||
| Daniel (6 February 2001) | ||||
| - A friendly person named "SM" (nntp at iname.com) pointed out that the VC | ||||
|   makefile in src/ needed the libpath set for the debug build to work. | ||||
|  | ||||
| - Daniel Gehriger stepped in to assist with the VC++ stuff Robert Weaver | ||||
|   brought up yesterday. | ||||
|  | ||||
| Daniel (5 February 2001) | ||||
| - Jun-ichiro itojun Hagino brought a big patch that brings IPv6-awareness to | ||||
|   a bunch of different areas within libcurl. | ||||
|  | ||||
| - Robert Weaver told me about the problems the MS VC++ 6.0 compiler has with | ||||
|   the 'static' keyword on a number of libcurl functions. I might need to add a | ||||
|   patch that redefines static when libcurl is compiled with that compiler. | ||||
|   How do I know when VC++ compiles, anyone? | ||||
|  | ||||
| Daniel (4 February 2001) | ||||
| - curl_getinfo() was extended with two new options: | ||||
|   CURLINFO_CONTENT_LENGTH_DOWNLOAD and CURLINFO_CONTENT_LENGTH_UPLOAD. They | ||||
|   return the full assumed content length of the transfer in the given | ||||
|   direction. The CURLINFO_CONTENT_LENGTH_DOWNLOAD will be the Content-Length: | ||||
|   size of a HTTP download. Added descriptions to the man page as well. This | ||||
|   was done after discussions with Bob Schader. | ||||
|  | ||||
| Daniel (3 February 2001) | ||||
| - Ingo Ralf Blum provided another fix that makes curl build under the more | ||||
|   recent cygwin installations. It seems they've changed the preset defines to | ||||
|   not include WIN32 anymore. | ||||
|  | ||||
| Version 7.6.1-pre2 | ||||
|  | ||||
| Daniel (31 January 2001) | ||||
| - Curl_read() and curl_read() now return a ssize_t for the size, as it had to | ||||
|   be able to return -1. The telnet support crashed due to this and there was a | ||||
|   possibility to weird behaviour all over. Linus Nielsen Feltzing helped me | ||||
|   find this. | ||||
|  | ||||
| - Added a configure.in check for a working getaddrinfo() if IPv6 is requested. | ||||
|   I also made the configure script feature --enable-debug which sets a couple | ||||
|   of compiler options when used. It assumes gcc. | ||||
|  | ||||
| Daniel (30 January 2001) | ||||
| - I finally took a stab at the long-term FIXME item I've had on myself, and | ||||
|   now libcurl will properly work when doing a HTTP range-request that follows | ||||
|   a Location:. Previously that would make libcurl fail saying that the server | ||||
|   doesn't seem to support range requests. | ||||
|  | ||||
| Daniel (29 January 2001) | ||||
| - I added a test case for the HTTP PUT resume thing (test case 33). | ||||
|  | ||||
| Version 7.6.1-pre1 | ||||
|  | ||||
| Daniel (29 January 2001) | ||||
| - Yet another Content-Range change. Ok now? Bob Schader checks from his end  | ||||
|   and it works for him. | ||||
|  | ||||
| Daniel (27 January 2001) | ||||
| - So the HTTP PUT resume fix wasn't good. There should appearantly be a | ||||
|   Content-Range header when resuming a PUT. | ||||
|  | ||||
| - I noticed I broke the download-check that verifies that a resumed HTTP | ||||
|   download is actually resumed. It got broke because my new 'httpreq' field | ||||
|   in the main curl struct. I should get slapped. I added a test case for | ||||
|   this now, so I won't be able to ruin this again without noticing. | ||||
|  | ||||
| - Added a test case for content-length verifying when downloading HTTP. | ||||
|  | ||||
| - Made the progress meter title say if the transfer is being transfered. It | ||||
|   makes the output slightly better for resumes. | ||||
|  | ||||
| - When dealing with Location: and HTTP return codes, libcurl will not attempt | ||||
|   to follow the spirit of RFC2616 better. It means that when POSTing to a | ||||
|   URL that is being following to a second place, the standard will judge on | ||||
|   what to do. All HTTP codes except 303 and 305 will cause curl to make a | ||||
|   second POST operation. 303 will make a GET and 305 is not yet supported. | ||||
|  | ||||
|   I also wrote two test cases for this POST/GET/Location stuff. | ||||
|  | ||||
| Version 7.6 | ||||
|  | ||||
| Daniel (26 January 2001) | ||||
| - Lots of mails back and forth with Bob Schader finally made me add a small | ||||
|   piece of code in the HTTP engine so that HTTP upload resume works. You can | ||||
|   now do an operation like 'curl -T file -C <offset> <URL>' and curl will PUT | ||||
|   the ending part of the file starting at given offet to the specified URL. | ||||
|  | ||||
| Version 7.6-pre4 | ||||
|  | ||||
| Daniel (25 January 2001) | ||||
| - I took hold of Rick Jones' question why we don't use recv() and send() for | ||||
|   reading/writing to the sockets and I've now modified the sread() and | ||||
|   swrite() macros to use them instead. If nothing else, they could be tested | ||||
|   in the next beta-round coming right up. | ||||
|  | ||||
| - Jeff Morrow found a problem with libcurl's usage of SSL_read() and supplied | ||||
|   his research results in how to fix this. It turns out we have to invoke the | ||||
|   function several times in some cases. The same goes for the SSL_write(). | ||||
|  | ||||
|   I made some rather drastic changes all over libcurl to make all writes and | ||||
|   reads get done on one single place so that this repeated-attempts thing | ||||
|   would only have to be implemented at one point. | ||||
|  | ||||
| - Rick Jones spotted that the 'total time' counter really didn't measure the | ||||
|   total time very accurate on subsecond levels. | ||||
|  | ||||
| - Johan Nilsson pointed out the need to more clearly specify that the timeout | ||||
|   value you set for a download is for the *entire* download. There's currently | ||||
|   no option available that sets a timeout for the connection phase only. | ||||
|  | ||||
| Daniel (24 January 2001) | ||||
| - Ingo Ralf Blum submitted a series of patches required to get curl to compile | ||||
|   properly with cygwin. | ||||
|  | ||||
| - Robert Weaver posted a fix for the win32 section of the curl_getenv() code | ||||
|   that corrected a potential memory leak. | ||||
|  | ||||
| - Added comments in a few files in a sudden attempt to make the sources more | ||||
|   easy to read and understand! | ||||
|  | ||||
| Daniel (23 January 2001) | ||||
| - Added simple IPv6 detection in the configure script and made the version | ||||
|   string add 'ipv6' to the enable section in that case. ENABLE_IPV6 will be | ||||
|   set if curl is compiled with IPv6 support enabled. | ||||
|  | ||||
| - Added a parser for IPv6-style specified IP-addresses in a URL. Thus, when | ||||
|   IPv6 gets enabled soon, we can use URLs like '[0::1]:80'... | ||||
|  | ||||
| - Made the URL globbing in the client possible to fail silently if there's an | ||||
|   error in the globbing. It makes it almost intuitive, so when you don't | ||||
|   follow the syntax rules, globbing is simply switched off and the raw string | ||||
|   is used instead. | ||||
|  | ||||
|   I still think we'll get problems with IPv6-style IP-addresses when we *want* | ||||
|   globbing on parts of the URL as the initial part of the URL will for sure | ||||
|   seriously confuse the globber. | ||||
|  | ||||
| Daniel (22 January 2001) | ||||
| - Bj<42>rn Stenberg supplied a progress meter patch that makes it look better even | ||||
|   during slow starts. Previously it made some silly assumptions... | ||||
|  | ||||
| - Added two FTP tests for -Q and -Q - stuff since it was being discussed on | ||||
|   the mailing list. Had to correct the ftpserver.pl too as it bugged slightly. | ||||
|  | ||||
| Daniel (19 January 2001) | ||||
| - Made the Location: parsers deal with any-length URLs. Thus I removed the last | ||||
|   code that restricts the length of URLs that curl supports. | ||||
|  | ||||
| - Added a --globoff test case (#28) and it quickly identified a memory problem | ||||
|   in src/main.c that I took care of. | ||||
|  | ||||
| Version 7.6-pre3 | ||||
|  | ||||
| Daniel (17 January 2001) | ||||
| - Made the two former files lib/download.c and lib/highlevel.c become the new | ||||
|   lib/transfer.c which makes more sense. I also did the rename from Transfer() | ||||
|   | ||||
| @@ -36,3 +36,10 @@ | ||||
|  | ||||
| /* Define if you have the Kerberos4 libraries (including -ldes) */ | ||||
| #undef KRB4 | ||||
|  | ||||
| /* Define if you want to enable IPv6 support */ | ||||
| #undef ENABLE_IPV6 | ||||
|  | ||||
| /* Define this to 'int' if ssize_t is not an available typedefed type */ | ||||
| #undef ssize_t | ||||
|  | ||||
|   | ||||
| @@ -23,6 +23,9 @@ | ||||
| /* Define to `unsigned' if <sys/types.h> doesn't define.  */ | ||||
| /* #undef size_t */ | ||||
|  | ||||
| /* Define this to 'int' if ssize_t is not an available typedefed type */ | ||||
| #define ssize_t int | ||||
|  | ||||
| /* Define if you have the ANSI C header files.  */ | ||||
| #define STDC_HEADERS 1 | ||||
|  | ||||
|   | ||||
							
								
								
									
										312
									
								
								config.h.in
									
									
									
									
									
								
							
							
						
						
									
										312
									
								
								config.h.in
									
									
									
									
									
								
							| @@ -1,312 +0,0 @@ | ||||
| /* config.h.in.  Generated automatically from configure.in by autoheader.  */ | ||||
|  | ||||
| /* Define if on AIX 3. | ||||
|    System headers sometimes define this. | ||||
|    We just want to avoid a redefinition error message.  */ | ||||
| #ifndef _ALL_SOURCE | ||||
| #undef _ALL_SOURCE | ||||
| #endif | ||||
|  | ||||
| /* Define to empty if the keyword does not work.  */ | ||||
| #undef const | ||||
|  | ||||
| /* Define as the return type of signal handlers (int or void).  */ | ||||
| #undef RETSIGTYPE | ||||
|  | ||||
| /* Define to `unsigned' if <sys/types.h> doesn't define.  */ | ||||
| #undef size_t | ||||
|  | ||||
| /* Define if you have the ANSI C header files.  */ | ||||
| #undef STDC_HEADERS | ||||
|  | ||||
| /* Define if you can safely include both <sys/time.h> and <time.h>.  */ | ||||
| #undef TIME_WITH_SYS_TIME | ||||
|  | ||||
| /* Define cpu-machine-OS */ | ||||
| #undef OS | ||||
|  | ||||
| /* Define if you have the gethostbyaddr_r() function with 5 arguments */ | ||||
| #undef HAVE_GETHOSTBYADDR_R_5 | ||||
|  | ||||
| /* Define if you have the gethostbyaddr_r() function with 7 arguments */ | ||||
| #undef HAVE_GETHOSTBYADDR_R_7 | ||||
|  | ||||
| /* Define if you have the gethostbyaddr_r() function with 8 arguments */ | ||||
| #undef HAVE_GETHOSTBYADDR_R_8 | ||||
|  | ||||
| /* Define if you have the gethostbyname_r() function with 3 arguments */ | ||||
| #undef HAVE_GETHOSTBYNAME_R_3 | ||||
|  | ||||
| /* Define if you have the gethostbyname_r() function with 5 arguments */ | ||||
| #undef HAVE_GETHOSTBYNAME_R_5 | ||||
|  | ||||
| /* Define if you have the gethostbyname_r() function with 6 arguments */ | ||||
| #undef HAVE_GETHOSTBYNAME_R_6 | ||||
|  | ||||
| /* Define if you have the inet_ntoa_r function declared. */ | ||||
| #undef HAVE_INET_NTOA_R_DECL | ||||
|  | ||||
| /* Define if you need the _REENTRANT define for some functions */ | ||||
| #undef NEED_REENTRANT | ||||
|  | ||||
| /* Define if you have the Kerberos4 libraries (including -ldes) */ | ||||
| #undef KRB4 | ||||
|  | ||||
| /* The number of bytes in a long double.  */ | ||||
| #undef SIZEOF_LONG_DOUBLE | ||||
|  | ||||
| /* The number of bytes in a long long.  */ | ||||
| #undef SIZEOF_LONG_LONG | ||||
|  | ||||
| /* Define if you have the RAND_screen function.  */ | ||||
| #undef HAVE_RAND_SCREEN | ||||
|  | ||||
| /* Define if you have the RAND_status function.  */ | ||||
| #undef HAVE_RAND_STATUS | ||||
|  | ||||
| /* Define if you have the closesocket function.  */ | ||||
| #undef HAVE_CLOSESOCKET | ||||
|  | ||||
| /* Define if you have the gethostbyaddr function.  */ | ||||
| #undef HAVE_GETHOSTBYADDR | ||||
|  | ||||
| /* Define if you have the gethostbyaddr_r function.  */ | ||||
| #undef HAVE_GETHOSTBYADDR_R | ||||
|  | ||||
| /* Define if you have the gethostbyname_r function.  */ | ||||
| #undef HAVE_GETHOSTBYNAME_R | ||||
|  | ||||
| /* Define if you have the gethostname function.  */ | ||||
| #undef HAVE_GETHOSTNAME | ||||
|  | ||||
| /* Define if you have the getpass_r function.  */ | ||||
| #undef HAVE_GETPASS_R | ||||
|  | ||||
| /* Define if you have the getservbyname function.  */ | ||||
| #undef HAVE_GETSERVBYNAME | ||||
|  | ||||
| /* Define if you have the gettimeofday function.  */ | ||||
| #undef HAVE_GETTIMEOFDAY | ||||
|  | ||||
| /* Define if you have the inet_addr function.  */ | ||||
| #undef HAVE_INET_ADDR | ||||
|  | ||||
| /* Define if you have the inet_ntoa function.  */ | ||||
| #undef HAVE_INET_NTOA | ||||
|  | ||||
| /* Define if you have the inet_ntoa_r function.  */ | ||||
| #undef HAVE_INET_NTOA_R | ||||
|  | ||||
| /* Define if you have the krb_get_our_ip_for_realm function.  */ | ||||
| #undef HAVE_KRB_GET_OUR_IP_FOR_REALM | ||||
|  | ||||
| /* Define if you have the localtime_r function.  */ | ||||
| #undef HAVE_LOCALTIME_R | ||||
|  | ||||
| /* Define if you have the perror function.  */ | ||||
| #undef HAVE_PERROR | ||||
|  | ||||
| /* Define if you have the select function.  */ | ||||
| #undef HAVE_SELECT | ||||
|  | ||||
| /* Define if you have the setvbuf function.  */ | ||||
| #undef HAVE_SETVBUF | ||||
|  | ||||
| /* Define if you have the sigaction function.  */ | ||||
| #undef HAVE_SIGACTION | ||||
|  | ||||
| /* Define if you have the signal function.  */ | ||||
| #undef HAVE_SIGNAL | ||||
|  | ||||
| /* Define if you have the socket function.  */ | ||||
| #undef HAVE_SOCKET | ||||
|  | ||||
| /* Define if you have the strcasecmp function.  */ | ||||
| #undef HAVE_STRCASECMP | ||||
|  | ||||
| /* Define if you have the strcmpi function.  */ | ||||
| #undef HAVE_STRCMPI | ||||
|  | ||||
| /* Define if you have the strdup function.  */ | ||||
| #undef HAVE_STRDUP | ||||
|  | ||||
| /* Define if you have the strftime function.  */ | ||||
| #undef HAVE_STRFTIME | ||||
|  | ||||
| /* Define if you have the stricmp function.  */ | ||||
| #undef HAVE_STRICMP | ||||
|  | ||||
| /* Define if you have the strlcpy function.  */ | ||||
| #undef HAVE_STRLCPY | ||||
|  | ||||
| /* Define if you have the strstr function.  */ | ||||
| #undef HAVE_STRSTR | ||||
|  | ||||
| /* Define if you have the tcgetattr function.  */ | ||||
| #undef HAVE_TCGETATTR | ||||
|  | ||||
| /* Define if you have the tcsetattr function.  */ | ||||
| #undef HAVE_TCSETATTR | ||||
|  | ||||
| /* Define if you have the uname function.  */ | ||||
| #undef HAVE_UNAME | ||||
|  | ||||
| /* Define if you have the <alloca.h> header file.  */ | ||||
| #undef HAVE_ALLOCA_H | ||||
|  | ||||
| /* Define if you have the <arpa/inet.h> header file.  */ | ||||
| #undef HAVE_ARPA_INET_H | ||||
|  | ||||
| /* Define if you have the <crypto.h> header file.  */ | ||||
| #undef HAVE_CRYPTO_H | ||||
|  | ||||
| /* Define if you have the <des.h> header file.  */ | ||||
| #undef HAVE_DES_H | ||||
|  | ||||
| /* Define if you have the <dlfcn.h> header file.  */ | ||||
| #undef HAVE_DLFCN_H | ||||
|  | ||||
| /* Define if you have the <err.h> header file.  */ | ||||
| #undef HAVE_ERR_H | ||||
|  | ||||
| /* Define if you have the <fcntl.h> header file.  */ | ||||
| #undef HAVE_FCNTL_H | ||||
|  | ||||
| /* Define if you have the <getopt.h> header file.  */ | ||||
| #undef HAVE_GETOPT_H | ||||
|  | ||||
| /* Define if you have the <io.h> header file.  */ | ||||
| #undef HAVE_IO_H | ||||
|  | ||||
| /* Define if you have the <krb.h> header file.  */ | ||||
| #undef HAVE_KRB_H | ||||
|  | ||||
| /* Define if you have the <malloc.h> header file.  */ | ||||
| #undef HAVE_MALLOC_H | ||||
|  | ||||
| /* Define if you have the <net/if.h> header file.  */ | ||||
| #undef HAVE_NET_IF_H | ||||
|  | ||||
| /* Define if you have the <netdb.h> header file.  */ | ||||
| #undef HAVE_NETDB_H | ||||
|  | ||||
| /* Define if you have the <netinet/if_ether.h> header file.  */ | ||||
| #undef HAVE_NETINET_IF_ETHER_H | ||||
|  | ||||
| /* Define if you have the <netinet/in.h> header file.  */ | ||||
| #undef HAVE_NETINET_IN_H | ||||
|  | ||||
| /* Define if you have the <openssl/crypto.h> header file.  */ | ||||
| #undef HAVE_OPENSSL_CRYPTO_H | ||||
|  | ||||
| /* Define if you have the <openssl/err.h> header file.  */ | ||||
| #undef HAVE_OPENSSL_ERR_H | ||||
|  | ||||
| /* Define if you have the <openssl/pem.h> header file.  */ | ||||
| #undef HAVE_OPENSSL_PEM_H | ||||
|  | ||||
| /* Define if you have the <openssl/rsa.h> header file.  */ | ||||
| #undef HAVE_OPENSSL_RSA_H | ||||
|  | ||||
| /* Define if you have the <openssl/ssl.h> header file.  */ | ||||
| #undef HAVE_OPENSSL_SSL_H | ||||
|  | ||||
| /* Define if you have the <openssl/x509.h> header file.  */ | ||||
| #undef HAVE_OPENSSL_X509_H | ||||
|  | ||||
| /* Define if you have the <pem.h> header file.  */ | ||||
| #undef HAVE_PEM_H | ||||
|  | ||||
| /* Define if you have the <rsa.h> header file.  */ | ||||
| #undef HAVE_RSA_H | ||||
|  | ||||
| /* Define if you have the <sgtty.h> header file.  */ | ||||
| #undef HAVE_SGTTY_H | ||||
|  | ||||
| /* Define if you have the <ssl.h> header file.  */ | ||||
| #undef HAVE_SSL_H | ||||
|  | ||||
| /* Define if you have the <stdlib.h> header file.  */ | ||||
| #undef HAVE_STDLIB_H | ||||
|  | ||||
| /* Define if you have the <sys/param.h> header file.  */ | ||||
| #undef HAVE_SYS_PARAM_H | ||||
|  | ||||
| /* Define if you have the <sys/select.h> header file.  */ | ||||
| #undef HAVE_SYS_SELECT_H | ||||
|  | ||||
| /* Define if you have the <sys/socket.h> header file.  */ | ||||
| #undef HAVE_SYS_SOCKET_H | ||||
|  | ||||
| /* Define if you have the <sys/sockio.h> header file.  */ | ||||
| #undef HAVE_SYS_SOCKIO_H | ||||
|  | ||||
| /* Define if you have the <sys/stat.h> header file.  */ | ||||
| #undef HAVE_SYS_STAT_H | ||||
|  | ||||
| /* Define if you have the <sys/time.h> header file.  */ | ||||
| #undef HAVE_SYS_TIME_H | ||||
|  | ||||
| /* Define if you have the <sys/types.h> header file.  */ | ||||
| #undef HAVE_SYS_TYPES_H | ||||
|  | ||||
| /* Define if you have the <termio.h> header file.  */ | ||||
| #undef HAVE_TERMIO_H | ||||
|  | ||||
| /* Define if you have the <termios.h> header file.  */ | ||||
| #undef HAVE_TERMIOS_H | ||||
|  | ||||
| /* Define if you have the <time.h> header file.  */ | ||||
| #undef HAVE_TIME_H | ||||
|  | ||||
| /* Define if you have the <unistd.h> header file.  */ | ||||
| #undef HAVE_UNISTD_H | ||||
|  | ||||
| /* Define if you have the <winsock.h> header file.  */ | ||||
| #undef HAVE_WINSOCK_H | ||||
|  | ||||
| /* Define if you have the <x509.h> header file.  */ | ||||
| #undef HAVE_X509_H | ||||
|  | ||||
| /* Define if you have the crypto library (-lcrypto).  */ | ||||
| #undef HAVE_LIBCRYPTO | ||||
|  | ||||
| /* Define if you have the dl library (-ldl).  */ | ||||
| #undef HAVE_LIBDL | ||||
|  | ||||
| /* Define if you have the nsl library (-lnsl).  */ | ||||
| #undef HAVE_LIBNSL | ||||
|  | ||||
| /* Define if you have the resolv library (-lresolv).  */ | ||||
| #undef HAVE_LIBRESOLV | ||||
|  | ||||
| /* Define if you have the resolve library (-lresolve).  */ | ||||
| #undef HAVE_LIBRESOLVE | ||||
|  | ||||
| /* Define if you have the socket library (-lsocket).  */ | ||||
| #undef HAVE_LIBSOCKET | ||||
|  | ||||
| /* Define if you have the ssl library (-lssl).  */ | ||||
| #undef HAVE_LIBSSL | ||||
|  | ||||
| /* Define if you have the ucb library (-lucb).  */ | ||||
| #undef HAVE_LIBUCB | ||||
|  | ||||
| /* Name of package */ | ||||
| #undef PACKAGE | ||||
|  | ||||
| /* Version number of package */ | ||||
| #undef VERSION | ||||
|  | ||||
| /* Number of bits in a file offset, on hosts where this is settable. */ | ||||
| #undef _FILE_OFFSET_BITS | ||||
|  | ||||
| /* Define to make ftello visible on some hosts (e.g. HP-UX 10.20). */ | ||||
| #undef _LARGEFILE_SOURCE | ||||
|  | ||||
| /* Define for large files, on AIX-style hosts. */ | ||||
| #undef _LARGE_FILES | ||||
|  | ||||
| /* Set to explicitly specify we don't want to use thread-safe functions */ | ||||
| #undef DISABLED_THREADSAFE | ||||
|  | ||||
							
								
								
									
										117
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								configure.in
									
									
									
									
									
								
							| @@ -26,6 +26,66 @@ dnl The install stuff has already been taken care of by the automake stuff | ||||
| dnl AC_PROG_INSTALL | ||||
| AC_PROG_MAKE_SET | ||||
|  | ||||
| dnl ************************************************************ | ||||
| dnl lame option to switch on debug options | ||||
| dnl | ||||
| AC_MSG_CHECKING([whether to enable debug options]) | ||||
| AC_ARG_ENABLE(debug, | ||||
| [  --enable-debug		Enable pedantic debug options | ||||
|   --disable-debug		Disable debug options], | ||||
| [ case "$enableval" in | ||||
|   no) | ||||
|        AC_MSG_RESULT(no) | ||||
|        ;; | ||||
|   *)   AC_MSG_RESULT(yes) | ||||
|  | ||||
|     CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG" | ||||
|     CFLAGS="-Wall -pedantic -g"  | ||||
|        ;; | ||||
|   esac ], | ||||
|        AC_MSG_RESULT(no) | ||||
| ) | ||||
|  | ||||
|  | ||||
| dnl | ||||
| dnl check for working getaddrinfo() | ||||
| dnl | ||||
| AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[ | ||||
|   AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[ | ||||
|   AC_TRY_RUN( [ | ||||
| #include <netdb.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
|  | ||||
| void main(void) { | ||||
|     struct addrinfo hints, *ai; | ||||
|     int error; | ||||
|  | ||||
|     memset(&hints, 0, sizeof(hints)); | ||||
|     hints.ai_family = AF_UNSPEC; | ||||
|     hints.ai_socktype = SOCK_STREAM; | ||||
|     error = getaddrinfo("127.0.0.1", "8080", &hints, &ai); | ||||
|     if (error) { | ||||
|         exit(1); | ||||
|     } | ||||
|     else { | ||||
|         exit(0); | ||||
|     } | ||||
| } | ||||
| ],[ | ||||
|   ac_cv_working_getaddrinfo="yes" | ||||
| ],[ | ||||
|   ac_cv_working_getaddrinfo="no" | ||||
| ],[ | ||||
|   ac_cv_working_getaddrinfo="yes" | ||||
| ])]) | ||||
| if test "$ac_cv_working_getaddrinfo" = "yes"; then | ||||
|   AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works]) | ||||
|   AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support]) | ||||
| fi | ||||
| ]) | ||||
|  | ||||
|  | ||||
| AC_DEFUN(CURL_CHECK_LOCALTIME_R, | ||||
| [ | ||||
|   dnl check for a few thread-safe functions | ||||
| @@ -237,6 +297,47 @@ exit (rc != 0 ? 1 : 0); }],[ | ||||
|  | ||||
| ]) | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Checks for IPv6 | ||||
| dnl ********************************************************************** | ||||
|  | ||||
| AC_MSG_CHECKING([whether to enable ipv6]) | ||||
| AC_ARG_ENABLE(ipv6, | ||||
| [  --enable-ipv6		Enable ipv6 (with ipv4) support | ||||
|   --disable-ipv6		Disable ipv6 support], | ||||
| [ case "$enableval" in | ||||
|   no) | ||||
|        AC_MSG_RESULT(no) | ||||
|        ipv6=no | ||||
|        ;; | ||||
|   *)   AC_MSG_RESULT(yes) | ||||
|        ipv6=yes | ||||
|        ;; | ||||
|   esac ], | ||||
|  | ||||
|   AC_TRY_RUN([ /* is AF_INET6 available? */ | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| main() | ||||
| { | ||||
|  if (socket(AF_INET6, SOCK_STREAM, 0) < 0) | ||||
|    exit(1); | ||||
|  else | ||||
|    exit(0); | ||||
| } | ||||
| ], | ||||
|   AC_MSG_RESULT(yes) | ||||
|   ipv6=yes, | ||||
|   AC_MSG_RESULT(no) | ||||
|   ipv6=no, | ||||
|   AC_MSG_RESULT(no) | ||||
|   ipv6=no | ||||
| )) | ||||
|  | ||||
| if test "$ipv6" = "yes"; then | ||||
|   CURL_CHECK_WORKING_GETADDRINFO | ||||
| fi | ||||
|  | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Checks for libraries. | ||||
| @@ -327,6 +428,10 @@ AC_MSG_CHECKING([if Kerberos4 support is requested]) | ||||
|  | ||||
| if test "$want_krb4" = yes | ||||
| then | ||||
|   if test "$ipv6" = "yes"; then | ||||
|     echo krb4 is not compatible with IPv6 | ||||
|     exit 1 | ||||
|   fi | ||||
|   AC_MSG_RESULT(yes) | ||||
|  | ||||
|   dnl Check for & handle argument to --with-krb4 | ||||
| @@ -554,6 +659,9 @@ AC_CHECK_SIZEOF(long double, 8) | ||||
| # check for 'long long' | ||||
| AC_CHECK_SIZEOF(long long, 4) | ||||
|  | ||||
| # check for ssize_t | ||||
| AC_CHECK_TYPE(ssize_t, int) | ||||
|  | ||||
| dnl Get system canonical name | ||||
| AC_CANONICAL_HOST | ||||
| AC_DEFINE_UNQUOTED(OS, "${host}") | ||||
| @@ -584,12 +692,16 @@ AC_CHECK_FUNCS( socket \ | ||||
|                 setvbuf \ | ||||
|                 sigaction \ | ||||
|                 signal \ | ||||
|                 getpass_r | ||||
|                 getpass_r \ | ||||
|                 strlcat | ||||
| ) | ||||
|  | ||||
| dnl removed 'getpass' check on October 26, 2000 | ||||
|  | ||||
| if test "$ac_cv_func_select" != "yes"; then | ||||
|   AC_MSG_ERROR(Can't work without an existing select() function) | ||||
| fi | ||||
| if test "$ac_cv_func_socket" != "yes"; then | ||||
|   AC_MSG_ERROR(Can't work without an existing socket() function) | ||||
| fi | ||||
|  | ||||
| @@ -621,5 +733,6 @@ AC_OUTPUT( Makefile \ | ||||
| 	   packages/Linux/Makefile \ | ||||
| 	   packages/Linux/RPM/Makefile \ | ||||
| 	   packages/Linux/RPM/curl.spec \ | ||||
| 	   packages/Linux/RPM/curl-ssl.spec ) | ||||
| 	   packages/Linux/RPM/curl-ssl.spec \ | ||||
|            tiny/Makefile ) | ||||
|  | ||||
|   | ||||
							
								
								
									
										99
									
								
								docs/FAQ
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								docs/FAQ
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| Updated: January 15, 2001 (http://curl.haxx.se/docs/faq.shtml) | ||||
| Updated: February 16, 2001 (http://curl.haxx.se/docs/faq.shtml) | ||||
|                                   _   _ ____  _      | ||||
|                               ___| | | |  _ \| |     | ||||
|                              / __| | | | |_) | |     | ||||
| @@ -30,6 +30,8 @@ FAQ | ||||
|   3.6 Does curl support javascript, ASP, XML, XHTML or HTML version Y? | ||||
|   3.7 Can I use curl to delete/rename a file through FTP? | ||||
|   3.8 How do I tell curl to follow HTTP redirects? | ||||
|   3.9 How do I use curl in PHP? | ||||
|   3.10 What about SOAP, WEBDAV, XML-RPC or similar protocols over HTTP? | ||||
|  | ||||
|  4. Running Problems | ||||
|   4.1 Problems connecting to SSL servers. | ||||
| @@ -52,6 +54,8 @@ FAQ | ||||
|   5.2 How can I receive all data into a large memory chunk? | ||||
|   5.3 How do I fetch multiple files with libcurl? | ||||
|   5.4 Does libcurl do Winsock initing on win32 systems? | ||||
|   5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ? | ||||
|   5.6 What about Keep-Alive or persistant connections? | ||||
|  | ||||
|  6. License Issues | ||||
|   6.1 I have a GPL program, can I use the libcurl library? | ||||
| @@ -103,8 +107,8 @@ FAQ | ||||
|   or with PHP. | ||||
|  | ||||
|   Curl is not a single-OS program. Curl exists, compiles, builds and runs | ||||
|   under a wide range of operating systems, including all modern Unixes, | ||||
|   Windows, Amiga, BeOS, OS/2, OS X, QNX etc. | ||||
|   under a wide range of operating systems, including all modern Unixes (and a | ||||
|   bunch of older ones too), Windows, Amiga, BeOS, OS/2, OS X, QNX etc. | ||||
|  | ||||
|   1.4 When will you make curl do XXXX ? | ||||
|  | ||||
| @@ -179,11 +183,8 @@ FAQ | ||||
|   2.2. Does curl work/build with other SSL libraries? | ||||
|  | ||||
|   Curl has been written to use OpenSSL, although I doubt there would be much | ||||
|   problems using a different library. I just don't know any other free one and | ||||
|   that has limited my possibilities to develop against anything else. | ||||
|  | ||||
|   If anyone does "port" curl to use a commercial SSL library, I am of course | ||||
|   very interested in getting the patch! | ||||
|   problems using a different library. If anyone does "port" curl to use a | ||||
|   different SSL library, I am of course very interested in getting the patch! | ||||
|  | ||||
|   2.3. Where can I find a copy of LIBEAY32.DLL? | ||||
|  | ||||
| @@ -227,7 +228,7 @@ FAQ | ||||
|  | ||||
|   You can't simply use -F or -d at your choice. The web server that will | ||||
|   receive your post assumes one of the formats. If the form you're trying to | ||||
|   "fake" sets the type to 'multipart/form-data', than and only then you must | ||||
|   "fake" sets the type to 'multipart/form-data', then and only then you must | ||||
|   use the -F type. In all the most common cases, you should use -d which then | ||||
|   causes a posting with the type 'application/x-www-form-urlencoded'. | ||||
|  | ||||
| @@ -278,6 +279,29 @@ FAQ | ||||
|  | ||||
|      curl -L http://redirector.com | ||||
|  | ||||
|   3.9 How do I use curl in PHP? | ||||
|  | ||||
|   PHP4 has the ability to use libcurl as an internal module if built with that | ||||
|   option enabled. You then get a set of extra functions that can be used | ||||
|   within your PHP programs. You find all details about those functions in the | ||||
|   curl section in the PHP manual, see the online version at: | ||||
|  | ||||
|         http://www.php.net/manual/ref.curl.php | ||||
|  | ||||
|   PHP also offers the option to run a command line, and then you can of course | ||||
|   invoke the curl tool using a command line. This is the way to use curl if | ||||
|   you're using PHP3 or PHP4 built without curl module support. | ||||
|  | ||||
|   3.10 What about SOAP, WEBDAV, XML-RPC or similar protocols over HTTP? | ||||
|  | ||||
|   Curl adheres to the HTTP spec, which basically means you can play with *any* | ||||
|   protocol that is built ontop of HTTP. Protocols such as SOAP, WEBDAV and | ||||
|   XML-RPC are all such ones. You can use -X to set custom requests and -H to | ||||
|   set custom headers (or replace internally generated ones). | ||||
|  | ||||
|   Using libcurl or PHP's curl modules is just as fine and you'd just use the | ||||
|   proper library options to do the same. | ||||
|  | ||||
| 4. Running Problems | ||||
|  | ||||
|   4.1. Problems connecting to SSL servers. | ||||
| @@ -309,6 +333,9 @@ FAQ | ||||
|   In win32, the standard DOS shell treats the %-letter specially and you may | ||||
|   need to quote the string properly when % is used in it. | ||||
|  | ||||
|   Also note that if you want the literal %-letter to be part of the data you | ||||
|   pass in a POST using -d/--data you must encode it as '%25'. | ||||
|  | ||||
|   4.3. How can I use {, }, [ or ] to specify multiple URLs? | ||||
|  | ||||
|   Because those letters have a special meaning to the shell, and to be used in | ||||
| @@ -407,7 +434,8 @@ FAQ | ||||
|   4.9. Curl can't authenticate to the server that requires NTLM? | ||||
|  | ||||
|   NTLM is a Microsoft proprietary protocol. Unfortunately, curl does not | ||||
|   currently support that. | ||||
|   currently support that. Proprietary formats are evil. You should not use | ||||
|   such ones. | ||||
|  | ||||
| 5. libcurl Issues | ||||
|  | ||||
| @@ -472,9 +500,28 @@ FAQ | ||||
|   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 ? | ||||
|  | ||||
|   Yes, but you cannot open a FILE * and pass the pointer to a DLL and have | ||||
|   that DLL use the FILE *. If you set CURLOPT_FILE you must also use | ||||
|   CURLOPT_WRITEFUNCTION as well to set a function that writes the file, even | ||||
|   if that simply writes the data to the specified FILE*. Similarly, if you use | ||||
|   CURLOPT_INFILE you must also specify CURLOPT_READFUNCTION. | ||||
|  | ||||
|   (Provided by Joel DeYoung and Bob Schader) | ||||
|  | ||||
|   5.6 What about Keep-Alive or persistant connections? | ||||
|  | ||||
|   This is closely related to issue 5.3. Since libcurl has no real support | ||||
|   for doing multiple file transfers, there's no support for Keep-Alive or | ||||
|   persistant connections either. | ||||
|  | ||||
|   This is of course subject to change as soon as libcurl gets support for | ||||
|   multiple files. Feel free to join in and make this change happen sooner! | ||||
|  | ||||
| 6. License Issues | ||||
|  | ||||
|   NOTE: This section is now updated to concern curl 7.5.2 or later! | ||||
|   NOTE: This section concerns curl 7.5.2 or later! | ||||
|  | ||||
|   Curl and libcurl are released under a MIT/X derivate license *or* the MPL, | ||||
|   the Mozilla Public License. To get a really good answer to your license | ||||
| @@ -492,27 +539,25 @@ FAQ | ||||
|  | ||||
|   6.2. I have a closed-source program, can I use the libcurl library? | ||||
|  | ||||
|   Yes. | ||||
|   Yes! | ||||
|  | ||||
|   libcurl does not put any restrictions on the program that uses the | ||||
|   library. | ||||
|   libcurl does not put any restrictions on the program that uses the library. | ||||
|  | ||||
|   6.3. I have a BSD licensed program, can I use the libcurl library? | ||||
|  | ||||
|   Yes. | ||||
|   Yes! | ||||
|  | ||||
|   libcurl does not put any restrictions on the program that uses the | ||||
|   library. | ||||
|   libcurl does not put any restrictions on the program that uses the library. | ||||
|  | ||||
|   6.4. I have a program that uses LGPL libraries, can I use libcurl? | ||||
|  | ||||
|   Yes. | ||||
|   Yes! | ||||
|  | ||||
|   The LGPL license don't clash with other licenses. | ||||
|   The LGPL license doesn't clash with other licenses. | ||||
|  | ||||
|   6.5. Can I modify curl/libcurl for my program and keep the changes secret? | ||||
|  | ||||
|   Yes. | ||||
|   Yes! | ||||
|  | ||||
|   The MIT/X derivate license practically allows you to do almost anything with | ||||
|   the sources, on the condition that the copyright texts in the sources are | ||||
| @@ -520,9 +565,11 @@ FAQ | ||||
|  | ||||
|   6.6. Can you please change the curl/libcurl license to XXXX? | ||||
|  | ||||
|   No. We carefully picked this license years ago and a large amount of people | ||||
|   have contributed with source code knowing that this is the license we | ||||
|   use. This license puts the restrictions we want on curl/libcurl and it does | ||||
|   not spread to other programs or libraries that use it. The recent dual | ||||
|   license modification should make it possible for everyone to use libcurl or | ||||
|   curl in their projects, no matter what license they already have in use. | ||||
|   No. | ||||
|  | ||||
|   We carefully picked this license years ago and a large amount of people have | ||||
|   contributed with source code knowing that this is the license we use. This | ||||
|   license puts the restrictions we want on curl/libcurl and it does not spread | ||||
|   to other programs or libraries that use it. The recent dual license | ||||
|   modification should make it possible for everyone to use libcurl or curl in | ||||
|   their projects, no matter what license they already have in use. | ||||
|   | ||||
| @@ -20,6 +20,7 @@ Misc | ||||
|  - compiles on win32 | ||||
|  - redirectable stderr | ||||
|  - use selected network interface for outgoing traffic | ||||
|  - IPv6 support | ||||
|  | ||||
| HTTP | ||||
|  - GET | ||||
| @@ -28,7 +29,7 @@ HTTP | ||||
|  - POST | ||||
|  - multipart POST | ||||
|  - authentication | ||||
|  - resume | ||||
|  - resume (both GET and PUT) | ||||
|  - follow redirects | ||||
|  - maximum amount of redirects to follow | ||||
|  - custom HTTP request | ||||
|   | ||||
							
								
								
									
										15
									
								
								docs/INSTALL
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								docs/INSTALL
									
									
									
									
									
								
							| @@ -84,9 +84,10 @@ UNIX | ||||
|  | ||||
|    KNOWN PROBLEMS | ||||
|  | ||||
|      If you happen to have autoconf installed, but a version older than | ||||
|      2.12 you will get into trouble. Then you can still build curl by | ||||
|      issuing these commands: (from Ralph Beckmann) | ||||
|      If you happen to have autoconf installed, but a version older than 2.12 | ||||
|      you will get into trouble. Then you can still build curl by issuing these | ||||
|      commands (note that this requires curl to be built staticly): (from Ralph | ||||
|      Beckmann) | ||||
|  | ||||
|        ./configure [...] | ||||
|        cd lib; make; cd .. | ||||
| @@ -139,6 +140,14 @@ UNIX | ||||
|  | ||||
|        ./configure --with-krb4=/usr/athena | ||||
|  | ||||
|      If your system support shared libraries, but you want to built a static | ||||
|      version only, you can disable building the shared version by using: | ||||
|  | ||||
|        ./configure --disable-shared | ||||
|  | ||||
|      If you're a curl developer and use gcc, you might want to enable more | ||||
|      debug options with the --enable-debug option. | ||||
|  | ||||
| Win32 | ||||
| ===== | ||||
|   | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
|                                      Updated for curl 7.6 on January 26, 2001 | ||||
|                                   _   _ ____  _      | ||||
|                               ___| | | |  _ \| |     | ||||
|                              / __| | | | |_) | |     | ||||
| @@ -12,13 +13,6 @@ INTERNALS | ||||
|  | ||||
|  Thus, the largest amount of code and complexity is in the library part. | ||||
|  | ||||
| SYMBOLS | ||||
| ======= | ||||
|  All symbols used internally must use a 'Curl_' prefix if they're used in more | ||||
|  than a single file. Single-file symbols must be made static. Public | ||||
|  (exported) symbols must use a 'curl_' prefix. (There are exceptions, but they | ||||
|  are destined to be changed to follow this pattern in the future.) | ||||
|  | ||||
| CVS | ||||
| === | ||||
|  All changes to the sources are committed to the CVS repository as soon as | ||||
| @@ -35,10 +29,11 @@ Windows vs Unix | ||||
|  There are a few differences in how to program curl the unix way compared to | ||||
|  the Windows way. The four perhaps most notable details are: | ||||
|  | ||||
|  1. Different function names for close(), read(), write() | ||||
|  1. Different function names for socket operations. | ||||
|  | ||||
|    In curl, this is solved with defines and macros, so that the source looks | ||||
|    the same at all places except for the header file that defines them. | ||||
|    the same at all places except for the header file that defines them. The | ||||
|    macros in use are sclose(), sread() and swrite(). | ||||
|  | ||||
|  2. Windows requires a couple of init calls for the socket stuff | ||||
|  | ||||
| @@ -187,6 +182,15 @@ Library | ||||
|  exists in lib/getpass.c. libcurl offers a custom callback that can be used | ||||
|  instead of this, but it doesn't change much to us. | ||||
|  | ||||
| Library Symbols | ||||
| =============== | ||||
|   | ||||
|  All symbols used internally in libcurl must use a 'Curl_' prefix if they're | ||||
|  used in more than a single file. Single-file symbols must be made | ||||
|  static. Public (exported) symbols must use a 'curl_' prefix. (There are | ||||
|  exceptions, but they are destined to be changed to follow this pattern in the | ||||
|  future.) | ||||
|  | ||||
| Return Codes and Informationals | ||||
| =============================== | ||||
|  | ||||
|   | ||||
							
								
								
									
										41
									
								
								docs/MANUAL
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								docs/MANUAL
									
									
									
									
									
								
							| @@ -726,16 +726,41 @@ KERBEROS4 FTP TRANSFER | ||||
|   There's no use for a password on the -u switch, but a blank one will make | ||||
|   curl ask for one and you already entered the real password to kauth. | ||||
|  | ||||
| MAILING LIST | ||||
| TELNET | ||||
|  | ||||
|   We have an open mailing list to discuss curl, its development and things | ||||
|   relevant to this. | ||||
|   The curl telnet support is basic and very easy to use. Curl passes all data | ||||
|   passed to it on stdin to the remote server. Connect to a remote telnet | ||||
|   server using a command line similar to: | ||||
|  | ||||
|   To subscribe, mail curl-request@contactor.se with "subscribe <fill in your | ||||
|   email address>" in the body. | ||||
|         curl telnet://remote.server.com | ||||
|  | ||||
|   To post to the list, mail curl@contactor.se. | ||||
|   And enter the data to pass to the server on stdin. The result will be sent | ||||
|   to stdout or to the file you specify with -o. | ||||
|  | ||||
|   To unsubcribe, mail curl-request@contactor.se with "unsubscribe <your | ||||
|   subscribed email address>" in the body. | ||||
|   You might want the -N/--no-buffer option to switch off the buffered output | ||||
|   for slow connections or similar. | ||||
|  | ||||
|   NOTE: the telnet protocol does not specify any way to login with a specified | ||||
|   user and password so curl can't do that automatically. To do that, you need | ||||
|   to track when the login prompt is received and send the username and | ||||
|   password accordingly. | ||||
|  | ||||
| MAILING LISTS | ||||
|  | ||||
|   For your convenience, we have several open mailing lists to discuss curl, | ||||
|   its development and things relevant to this. | ||||
|  | ||||
|   To subscribe to the main curl list, mail curl-request@contactor.se with | ||||
|   "subscribe <fill in your email address>" in the body. | ||||
|  | ||||
|   To subscribe to the libcurl users list, follow the instructions at | ||||
|   http://curl.haxx.se/mail/ | ||||
|  | ||||
|   To subscribe to the curl announce list, to only get information about new | ||||
|   releases, follow the instructions at http://curl.haxx.se/mail/ | ||||
|  | ||||
|   To subscribe to the curl-and-PHP list in which curl using with PHP is | ||||
|   discussed, follow the instructions at http://curl.haxx.se/mail/ | ||||
|  | ||||
|   Please direct curl questions, feature requests and trouble reports to one of | ||||
|   these mailing lists instead of mailing any individual. | ||||
|   | ||||
							
								
								
									
										11
									
								
								docs/TODO
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								docs/TODO
									
									
									
									
									
								
							| @@ -23,11 +23,8 @@ For the future | ||||
|    URLs mentioned in the list. I figure -O or something would have to be | ||||
|    implied by such an action. | ||||
|  | ||||
|  * Improve the regular progress meter with --continue is used. It should be | ||||
|    noticable when there's a resume going on. | ||||
|  | ||||
|  * Add a command line option that allows the output file to get the same time | ||||
|    stamp as the remote file. We already are capable of fetching the remote | ||||
|    stamp as the remote file. libcurl already is capable of fetching the remote | ||||
|    file's date. | ||||
|  | ||||
|  * Make the SSL layer option capable of using the Mozilla Security Services as | ||||
| @@ -58,13 +55,15 @@ For the future | ||||
|    started in October 1999 but halted again since it proved more work than we | ||||
|    thought. It is still a good idea to implement though. | ||||
|  | ||||
|  * Authentication: NTLM. It would be cool to support that MS crap called NTLM | ||||
|  * Authentication: NTLM. It would be  to support that MS crap called NTLM | ||||
|    authentication. MS proxies and servers sometime require that. Since that | ||||
|    protocol is a proprietary one, it involves reverse engineering and network | ||||
|    sniffing. This should however be a library-based functionality. There are a | ||||
|    few different efforts "out there" to make open source HTTP clients support | ||||
|    this and it should be possible to take advantage of other people's hard | ||||
|    work. http://modntlm.sourceforge.net/ is one. | ||||
|    work. http://modntlm.sourceforge.net/ is one. There's a web page at | ||||
|    http://www.innovation.ch/java/ntlm.html that contains detailed reverse- | ||||
|    engineered info. | ||||
|  | ||||
|  * RFC2617 compliance, "Digest Access Authentication" | ||||
|    A valid test page seem to exist at: | ||||
|   | ||||
							
								
								
									
										26
									
								
								docs/curl.1
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								docs/curl.1
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | ||||
| .\" nroff -man curl.1 | ||||
| .\" Written by Daniel Stenberg | ||||
| .\" | ||||
| .TH curl 1 "9 January 2001" "Curl 7.6" "Curl Manual" | ||||
| .TH curl 1 "19 January 2001" "Curl 7.6" "Curl Manual" | ||||
| .SH NAME | ||||
| curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or | ||||
| HTTPS syntax. | ||||
| @@ -205,6 +205,12 @@ To read the file's content from stdin insted of a file, use - where the file | ||||
| name should've been. This goes for both @ and < constructs. | ||||
|  | ||||
| This option can be used multiple times. | ||||
| .IP "-g/--globoff" | ||||
| This option switches off the "URL globbing parser". When you set this option, | ||||
| you can specify URLs that contain the letters {}[] without having them being | ||||
| interpreted by curl itself. Note that these letters are not normal legal URL | ||||
| contents but they should be encoded according to the URI standard. (Option | ||||
| added in curl 7.6) | ||||
| .IP "-h/--help" | ||||
| Usage help. | ||||
| .IP "-H/--header <header>" | ||||
| @@ -419,11 +425,14 @@ If this option is used twice, the second will again disable mute. | ||||
| When used with -s it makes curl show error message if it fails. | ||||
|  | ||||
| If this option is used twice, the second will again disable show error. | ||||
| .IP "-t/--upload" | ||||
| .B Deprecated. Use '-T -' instead. | ||||
| Transfer the stdin data to the specified file. Curl will read | ||||
| everything from stdin until EOF and store with the supplied name. If | ||||
| this is used on a http(s) server, the PUT command will be used. | ||||
| .IP "-t/--telnet-option <OPT=val>" | ||||
| Pass options to the telnet protocol. Supported options are: | ||||
|  | ||||
| TTYPE=<term> Sets the terminal type. | ||||
|  | ||||
| XDISPLOC=<X display> Sets the X display location. | ||||
|  | ||||
| NEW_ENV=<var,val> Sets an environment variable. | ||||
| .IP "-T/--upload-file <file>" | ||||
| Like -t, but this transfers the specified local file. If there is no | ||||
| file part in the specified URL, Curl will append the local file | ||||
| @@ -752,7 +761,7 @@ If you do find bugs, mail them to curl-bug@haxx.se. | ||||
|  - Lars J. Aas <larsa@sim.no> | ||||
|  - J<>rn Hartroth <Joern.Hartroth@computer.org> | ||||
|  - Matthew Clarke <clamat@van.maves.ca> | ||||
|  - Linus Nielsen <Linus.Nielsen@haxx.se> | ||||
|  - Linus Nielsen Feltzing <linus@haxx.se> | ||||
|  - Felix von Leitner <felix@convergence.de> | ||||
|  - Dan Zitter <dzitter@zitter.net> | ||||
|  - Jongki Suwandi <Jongki.Suwandi@eng.sun.com> | ||||
| @@ -780,6 +789,9 @@ If you do find bugs, mail them to curl-bug@haxx.se. | ||||
|  - Alexander Kourakos <awk@users.sourceforge.net> | ||||
|  - James Griffiths <griffiths_james@yahoo.com> | ||||
|  - Loic Dachary <loic@senga.org> | ||||
|  - Robert Weaver <robert.weaver@sabre.com> | ||||
|  - Ingo Ralf Blum <ingoralfblum@ingoralfblum.com> | ||||
|  - Jun-ichiro itojun Hagino <itojun@iijlab.net> | ||||
|  | ||||
| .SH WWW | ||||
| http://curl.haxx.se | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" Written by daniel@haxx.se | ||||
| .\" | ||||
| .TH curl_easy_init 3 "22 November 2000" "Curl 7.5" "libcurl Manual" | ||||
| .TH curl_easy_init 3 "4 February 2001" "Curl 7.6.1" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_easy_getinfo - Extract information from a curl session (added in 7.4) | ||||
| .SH SYNOPSIS | ||||
| @@ -81,6 +81,14 @@ than one request if FOLLOWLOCATION is true. | ||||
| Pass a pointer to a long to receive the result of the certification | ||||
| verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to | ||||
| curl_easy_setopt). (Added in 7.4.2) | ||||
| .TP | ||||
| .B CURLINFO_CONTENT_LENGTH_DOWNLOAD | ||||
| Pass a pointer to a double to receive the content-length of the download. | ||||
| (Added in 7.6.1) | ||||
| .TP | ||||
| .B CURLINFO_CONTENT_LENGTH_UPLOAD | ||||
| Pass a pointer to a double to receive the specified size of the upload. | ||||
| (Added in 7.6.1) | ||||
| .PP | ||||
|  | ||||
| .SH RETURN VALUE | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" Written by daniel@haxx.se | ||||
| .\" | ||||
| .TH curl_easy_perform 3 "26 May 2000" "Curl 7.0" "libcurl Manual" | ||||
| .TH curl_easy_perform 3 "1 Mar 2001" "Curl 7.0" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_easy_perform - Do the actual transfer in a "easy" session | ||||
| .SH SYNOPSIS | ||||
| @@ -16,12 +16,16 @@ are made, and will perform the transfer as described in the options. | ||||
| It must be called with the same | ||||
| .I handle | ||||
| as input as the curl_easy_init call returned. | ||||
|  | ||||
| You are only allowed to call this function once using the same handle. If you | ||||
| want to do repeated calls, you must call curl_easy_cleanup and curl_easy_init | ||||
| again first. | ||||
| .SH RETURN VALUE | ||||
| 0 means everything was ok, non-zero means an error occurred as | ||||
| .I <curl/curl.h> | ||||
| defines. If the CURLOPT_ERRORBUFFER was set with | ||||
| .I curl_easy_setopt | ||||
| there willo be a readable error message in the error buffer when non-zero is | ||||
| there will be a readable error message in the error buffer when non-zero is | ||||
| returned. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_easy_init "(3), " curl_easy_setopt "(3), " | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" Written by daniel@haxx.se | ||||
| .\" | ||||
| .TH curl_easy_setopt 3 "28 November 2000" "Curl 7.5" "libcurl Manual" | ||||
| .TH curl_easy_setopt 3 "2 February 2001" "Curl 7.5" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_easy_setopt - Set curl easy-session options | ||||
| .SH SYNOPSIS | ||||
| @@ -35,6 +35,12 @@ Data pointer to pass instead of FILE * to the file write function. Note that | ||||
| if you specify the | ||||
| .I CURLOPT_WRITEFUNCTION | ||||
| , this is the pointer you'll get as input. | ||||
|  | ||||
| NOTE: If you're using libcurl as a win32 .DLL, you MUST use a | ||||
| .I CURLOPT_WRITEFUNCTION | ||||
| if you set the | ||||
| .I CURLOPT_FILE | ||||
| option. | ||||
| .TP | ||||
| .B CURLOPT_WRITEFUNCTION | ||||
| Function pointer that should use match the following prototype: | ||||
| @@ -53,6 +59,12 @@ Data pointer to pass instead of FILE * to the file read function. Note that if | ||||
| you specify the | ||||
| .I CURLOPT_READFUNCTION | ||||
| , this is the pointer you'll get as input. | ||||
|  | ||||
| NOTE: If you're using libcurl as a win32 .DLL, you MUST use a | ||||
| .I CURLOPT_READFUNCTION | ||||
| if you set the | ||||
| .I CURLOPT_INFILE | ||||
| option. | ||||
| .TP | ||||
| .B CURLOPT_READFUNCTION | ||||
| Function pointer that should use match the following prototype: | ||||
|   | ||||
| @@ -2,13 +2,13 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" Written by daniel@haxx.se | ||||
| .\" | ||||
| .TH curl_formparse 3 "6 June 2000" "Curl 7.0" "libcurl Manual" | ||||
| .TH curl_formparse 3 "22 February 2001" "Curl 7.0" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_formparse - add a section to a multipart/formdata HTTP POST | ||||
| .SH SYNOPSIS | ||||
| .B #include <curl/curl.h> | ||||
| .sp | ||||
| .BI "CURLcode *curl_formparse(char *" string, "struct HttpPost **" firstitem, | ||||
| .BI "CURLcode curl_formparse(char *" string, "struct HttpPost **" firstitem, | ||||
| .BI "struct HttpPost ** "lastitem ");" | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| @@ -42,14 +42,14 @@ Add a form field named 'name' with the contents as read from the local files | ||||
| named 'filename1' and 'filename2'. This is identical to the upper, except that | ||||
| you get the contents of several files in one section. | ||||
| .TP | ||||
| .B [name]=@[filename];[content-type] | ||||
| .B [name]=@[filename];[type=<content-type>] | ||||
| Whenever you specify a file to read from, you can optionally specify the | ||||
| content-type as well. The content-type is passed to the server together with | ||||
| the contents of the file. curl_formparse() will guess content-type for a | ||||
| number of well-known extensions and otherwise it will set it to binary. You | ||||
| can override the internal decision by using this option. | ||||
| .TP | ||||
| .B [name]=@[filename1,filename2,...];[content-type] | ||||
| .B [name]=@[filename1,filename2,...];[type=<content-type>] | ||||
| When you specify several files to read the contents from, you can set the | ||||
| content-type for all of them in the same way as with a single file. | ||||
| .PP | ||||
|   | ||||
| @@ -2,14 +2,14 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" Written by daniel@haxx.se | ||||
| .\" | ||||
| .TH curl_slist_append 3 "2 June 2000" "Curl 7.0" "libcurl Manual" | ||||
| .TH curl_slist_append 3 "1 Mar 2001" "Curl 7.7" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_slist_append - add a string to an slist | ||||
| .SH SYNOPSIS | ||||
| .B #include <curl/curl.h> | ||||
| .sp | ||||
| .BI "struct curl_slist *curl_slist_append(struct curl_slit *" list, | ||||
| .BI "char * "string ");" | ||||
| .BI "const char * "string ");" | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| curl_slist_append() appends a specified string to a linked list of | ||||
|   | ||||
| @@ -5,7 +5,9 @@ | ||||
| AUTOMAKE_OPTIONS = foreign no-dependencies | ||||
|  | ||||
| EXTRA_DIST =  | ||||
| 	README curlgtk.c sepheaders.c simple.c | ||||
| 	README curlgtk.c sepheaders.c simple.c postit.c \ | ||||
| 	win32sockets.c \ | ||||
| 	getpageinvar.php simpleget.php simplepost.php | ||||
|  | ||||
| all: | ||||
| 	@echo "done" | ||||
|   | ||||
| @@ -6,3 +6,6 @@ advantage of libcurl. | ||||
|  | ||||
| If you end up with other small but still useful example sources, please mail | ||||
| them for submission in future packages and on the web site. | ||||
|  | ||||
| There are examples for different languages and environments. Browse around to | ||||
| find those that fit you. | ||||
|   | ||||
| @@ -1,4 +1,12 @@ | ||||
| /* curlgtk.c */ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  */ | ||||
| /* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */ | ||||
| /* an attempt to use the curl library in concert with a gtk-threaded application */ | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								docs/examples/getpageinvar.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								docs/examples/getpageinvar.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| # | ||||
| # The PHP curl module supports the received page to be returned in a variable | ||||
| # if told. | ||||
| # | ||||
| $ch = curl_init(); | ||||
|  | ||||
| curl_setopt($ch, CURLOPT_URL,"http://www.myurl.com/"); | ||||
| curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); | ||||
| $result=curl_exec ($ch); | ||||
| curl_close ($ch); | ||||
							
								
								
									
										71
									
								
								docs/examples/postit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								docs/examples/postit.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  * | ||||
|  * Example code that uploads a file name 'foo' to a remote script that accepts | ||||
|  * "HTML form based" (as described in RFC1738) uploads using HTTP POST. | ||||
|  * | ||||
|  * The imaginary form we'll fill in looks like: | ||||
|  * | ||||
|  * <form method="post" enctype="multipart/form-data" action="examplepost.cgi"> | ||||
|  * Enter file: <input type="file" name="sendfile" size="40"> | ||||
|  * Enter file name: <input type="text" name="filename" size="30"> | ||||
|  * <input type="submit" value="send" name="submit"> | ||||
|  * </form> | ||||
|  * | ||||
|  * This exact source code has not been verified to work. | ||||
|  */ | ||||
|  | ||||
| /* to make this work under windows, use the win32-functions from the | ||||
|    win32socket.c file as well */ | ||||
|  | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include <curl/curl.h> | ||||
| #include <curl/types.h> | ||||
| #include <curl/easy.h> | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|   CURL *curl; | ||||
|   CURLcode res; | ||||
|  | ||||
|   struct HttpPost *formpost=NULL; | ||||
|   struct HttpPost *lastptr=NULL; | ||||
|  | ||||
|   /* Fill in the file upload field */ | ||||
|   curl_formparse("sendfile=@foo", | ||||
|                  &formpost, | ||||
|                  &lastptr); | ||||
|  | ||||
|   /* Fill in the filename field */ | ||||
|   curl_formparse("filename=foo", | ||||
|                  &formpost, | ||||
|                  &lastptr); | ||||
|    | ||||
|  | ||||
|   /* Fill in the submit field too, even if this is rarely needed */ | ||||
|   curl_formparse("submit=send", | ||||
|                  &formpost, | ||||
|                  &lastptr); | ||||
|  | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     /* what URL that receives this POST */ | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, "http://curl.haxx.se/examplepost.cgi"); | ||||
|     curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); | ||||
|     res = curl_easy_perform(curl); | ||||
|  | ||||
|     /* always cleanup */ | ||||
|     curl_easy_cleanup(curl); | ||||
|  | ||||
|     /* then cleanup the formpost chain */ | ||||
|     curl_formfree(formpost); | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,3 +1,16 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  */ | ||||
|  | ||||
| /* to make this work under windows, use the win32-functions from the | ||||
|    win32socket.c file as well */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
|   | ||||
| @@ -1,9 +1,22 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include <curl/curl.h> | ||||
| #include <curl/types.h> | ||||
| #include <curl/easy.h> | ||||
|  | ||||
| /* to make this work under windows, use the win32-functions from the | ||||
|    win32socket.c file as well */ | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|   CURL *curl; | ||||
|   | ||||
							
								
								
									
										13
									
								
								docs/examples/simpleget.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/examples/simpleget.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| # | ||||
| # A very simple example that gets a HTTP page. | ||||
| # | ||||
|  | ||||
| $ch = curl_init(); | ||||
|  | ||||
| curl_setopt ($ch, CURLOPT_URL, "http://www.zend.com/"); | ||||
| curl_setopt ($ch, CURLOPT_HEADER, 0); | ||||
|  | ||||
| curl_exec ($ch); | ||||
|  | ||||
| curl_close ($ch); | ||||
|  | ||||
							
								
								
									
										12
									
								
								docs/examples/simplepost.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docs/examples/simplepost.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| # | ||||
| # A very simple PHP example that sends a HTTP POST to a remote site | ||||
| # | ||||
|  | ||||
| $ch = curl_init(); | ||||
|  | ||||
| curl_setopt($ch, CURLOPT_URL,"http://www.mysite.com/tester.phtml"); | ||||
| curl_setopt($ch, CURLOPT_POST, 1); | ||||
| curl_setopt($ch, CURLOPT_POSTFIELDS, "postvar1=value1&postvar2=value2&postvar3=value3"); | ||||
|  | ||||
| curl_exec ($ch); | ||||
| curl_close ($ch);  | ||||
							
								
								
									
										40
									
								
								docs/examples/win32sockets.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								docs/examples/win32sockets.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * These are example functions doing socket init that Windows | ||||
|  * require. If you don't use windows, you can safely ignore this crap. | ||||
|  */ | ||||
|  | ||||
| static void win32_cleanup(void) | ||||
| { | ||||
|   WSACleanup(); | ||||
| } | ||||
|  | ||||
| static CURLcode win32_init(void) | ||||
| { | ||||
|   WORD wVersionRequested;   | ||||
|   WSADATA wsaData;  | ||||
|   int err;  | ||||
|   wVersionRequested = MAKEWORD(1, 1);  | ||||
|      | ||||
|   err = WSAStartup(wVersionRequested, &wsaData);  | ||||
|      | ||||
|   if (err != 0)  | ||||
|     /* Tell the user that we couldn't find a useable */  | ||||
|     /* winsock.dll.     */  | ||||
|     return 1; | ||||
|      | ||||
|   /* Confirm that the Windows Sockets DLL supports 1.1.*/  | ||||
|   /* Note that if the DLL supports versions greater */  | ||||
|   /* than 1.1 in addition to 1.1, it will still return */  | ||||
|   /* 1.1 in wVersion since that is the version we */  | ||||
|   /* requested. */  | ||||
|      | ||||
|   if ( LOBYTE( wsaData.wVersion ) != 1 ||  | ||||
|        HIBYTE( wsaData.wVersion ) != 1 ) {  | ||||
|     /* Tell the user that we couldn't find a useable */  | ||||
|  | ||||
|     /* winsock.dll. */  | ||||
|     WSACleanup();  | ||||
|     return 1;  | ||||
|   } | ||||
|   return 0; /* 0 is ok */ | ||||
| } | ||||
| @@ -158,6 +158,9 @@ typedef enum { | ||||
|   CURLE_BAD_PASSWORD_ENTERED, /* when the my_getpass() returns fail */ | ||||
|   CURLE_TOO_MANY_REDIRECTS , /* catch endless re-direct loops */ | ||||
|  | ||||
|   CURLE_UNKNOWN_TELNET_OPTION , /* User specified an unknown option */ | ||||
|   CURLE_TELNET_OPTION_SYNTAX , /* Malformed telnet option */ | ||||
|  | ||||
|   CURL_LAST | ||||
| } CURLcode; | ||||
|  | ||||
| @@ -166,10 +169,6 @@ typedef enum { | ||||
|  | ||||
| #define CURL_ERROR_SIZE 256 | ||||
|  | ||||
| /* maximum URL length we deal with in headers */ | ||||
| #define URL_MAX_LENGTH 4096  | ||||
| #define URL_MAX_LENGTH_TXT "4095" | ||||
|  | ||||
| /* name is uppercase CURLOPT_<name>, | ||||
|    type is one of the defined CURLOPTTYPE_<type> | ||||
|    number is unique identifier */ | ||||
| @@ -410,6 +409,9 @@ typedef enum { | ||||
|      document! Pass a NULL to shut it off. */ | ||||
|   CINIT(FILETIME, OBJECTPOINT, 69), | ||||
|  | ||||
|   /* This points to a linked list of telnet options */ | ||||
|   CINIT(TELNETOPTIONS, OBJECTPOINT, 70), | ||||
|  | ||||
|   CURLOPT_LASTENTRY /* the last unusued */ | ||||
| } CURLoption; | ||||
|  | ||||
| @@ -456,8 +458,8 @@ char *curl_getenv(char *variable); | ||||
| char *curl_version(void); | ||||
|  | ||||
| /* This is the version number */ | ||||
| #define LIBCURL_VERSION "7.6-pre3" | ||||
| #define LIBCURL_VERSION_NUM 0x070600 | ||||
| #define LIBCURL_VERSION "7.7-alpha2" | ||||
| #define LIBCURL_VERSION_NUM 0x070000 | ||||
|  | ||||
| /* linked-list structure for the CURLOPT_QUOTE option (and other) */ | ||||
| struct curl_slist { | ||||
| @@ -465,184 +467,8 @@ struct curl_slist { | ||||
| 	struct curl_slist	*next; | ||||
| }; | ||||
|  | ||||
| struct curl_slist *curl_slist_append(struct curl_slist *list, char *data); | ||||
| void curl_slist_free_all(struct curl_slist *list); | ||||
|  | ||||
| /* | ||||
|  * NAME	curl_init() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Inits libcurl globally. This must be used before any libcurl calls can | ||||
|  * be used. This may install global plug-ins or whatever. (This does not | ||||
|  * do winsock inits in Windows.) | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * curl_init(); | ||||
|  * | ||||
|  */ | ||||
| CURLcode curl_init(void); | ||||
|  | ||||
| /* | ||||
|  * NAME	curl_init() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Frees libcurl globally. This must be used after all libcurl calls have | ||||
|  * been used. This may remove global plug-ins or whatever. (This does not | ||||
|  * do winsock cleanups in Windows.) | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * curl_free(curl); | ||||
|  * | ||||
|  */ | ||||
| void curl_free(void); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_open() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Opens a general curl session. It does not try to connect or do anything | ||||
|  * on the network because of this call. The specified URL is only required | ||||
|  * to enable curl to figure out what protocol to "activate". | ||||
|  * | ||||
|  * A session should be looked upon as a series of requests to a single host.  A | ||||
|  * session interacts with one host only, using one single protocol. | ||||
|  * | ||||
|  * The URL is not required. If set to "" or NULL, it can still be set later | ||||
|  * using the curl_setopt() function. If the curl_connect() function is called | ||||
|  * without the URL being known, it will return error. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLcode result; | ||||
|  * CURL *curl; | ||||
|  * result = curl_open(&curl, "http://curl.haxx.nu/libcurl/"); | ||||
|  * if(result != CURL_OK) { | ||||
|  *   return result; | ||||
|  * } | ||||
|  * */ | ||||
| CURLcode curl_open(CURL **curl, char *url); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_setopt() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Sets a particular option to the specified value. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURL curl; | ||||
|  * curl_setopt(curl, CURL_HTTP_FOLLOW_LOCATION, TRUE); | ||||
|  */ | ||||
| CURLcode curl_setopt(CURL *handle, CURLoption option, ...); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_close() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Closes a session previously opened with curl_open() | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURL *curl; | ||||
|  * CURLcode result; | ||||
|  * | ||||
|  * result = curl_close(curl); | ||||
|  */ | ||||
| CURLcode curl_close(CURL *curl); /* the opposite of curl_open() */ | ||||
|  | ||||
| CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, | ||||
|                    size_t *n); | ||||
| CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, | ||||
|                     size_t *n); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_connect() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Connects to the peer server and performs the initial setup. This function | ||||
|  * writes a connect handle to its second argument that is a unique handle for | ||||
|  * this connect. This allows multiple connects from the same handle returned | ||||
|  * by curl_open(). | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLCode result; | ||||
|  * CURL curl; | ||||
|  * CURLconnect connect; | ||||
|  * result = curl_connect(curl, &connect); | ||||
|  */ | ||||
|  | ||||
| CURLcode curl_connect(CURL *curl, CURLconnect **in_connect); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_do() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * (Note: May 3rd 2000: this function does not currently allow you to | ||||
|  * specify a document, it will use the one set previously) | ||||
|  * | ||||
|  * This function asks for the particular document, file or resource that | ||||
|  * resides on the server we have connected to. You may specify a full URL, | ||||
|  * just an absolute path or even a relative path. That means, if you're just | ||||
|  * getting one file from the remote site, you can use the same URL as input | ||||
|  * for both curl_open() as well as for this function. | ||||
|  * | ||||
|  * In the even there is a host name, port number, user name or password parts | ||||
|  * in the URL, you can use the 'flags' argument to ignore them completely, or | ||||
|  * at your choice, make the function fail if you're trying to get a URL from | ||||
|  * different host than you connected to with curl_connect(). | ||||
|  * | ||||
|  * You can only get one document at a time using the same connection. When one | ||||
|  * document has been received you can although request again. | ||||
|  * | ||||
|  * When the transfer is done, curl_done() MUST be called. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLCode result; | ||||
|  * char *url; | ||||
|  * CURLconnect *connect; | ||||
|  * result = curl_do(connect, url, CURL_DO_NONE); */ | ||||
| CURLcode curl_do(CURLconnect *in_conn); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_done() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * When the transfer following a curl_do() call is done, this function should | ||||
|  * get called. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLCode result; | ||||
|  * char *url; | ||||
|  * CURLconnect *connect; | ||||
|  * result = curl_done(connect); */ | ||||
| CURLcode curl_done(CURLconnect *connect); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_disconnect() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Disconnects from the peer server and performs connection cleanup. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLcode result; | ||||
|  * CURLconnect *connect; | ||||
|  * result = curl_disconnect(connect); */ | ||||
| CURLcode curl_disconnect(CURLconnect *connect); | ||||
| struct curl_slist *curl_slist_append(struct curl_slist *, const char *); | ||||
| void curl_slist_free_all(struct curl_slist *); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_getdate() | ||||
| @@ -680,9 +506,16 @@ typedef enum { | ||||
|   CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13, | ||||
|   CURLINFO_FILETIME         = CURLINFO_LONG   + 14, | ||||
|  | ||||
|   CURLINFO_LASTONE          = 15 | ||||
|   CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15, | ||||
|   CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16, | ||||
|  | ||||
|   CURLINFO_LASTONE          = 17 | ||||
| } CURLINFO; | ||||
|  | ||||
| /* unfortunately, the easy.h include file needs the options and info stuff | ||||
|    before it can be included! */ | ||||
| #include <curl/easy.h> /* nothing in curl is fun without the easy stuff */ | ||||
|  | ||||
| /* | ||||
|  * NAME curl_getinfo() | ||||
|  * | ||||
| @@ -697,6 +530,20 @@ typedef enum { | ||||
|  */ | ||||
| CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...); | ||||
|  | ||||
|  | ||||
| typedef enum { | ||||
|   CURLCLOSEPOLICY_NONE, /* first, never use this */ | ||||
|  | ||||
|   CURLCLOSEPOLICY_OLDEST, | ||||
|   CURLCLOSEPOLICY_LEAST_RECENTLY_USED, | ||||
|   CURLCLOSEPOLICY_LEAST_TRAFFIC, | ||||
|   CURLCLOSEPOLICY_SLOWEST, | ||||
|   CURLCLOSEPOLICY_CALLBACK, | ||||
|   | ||||
|   CURLCLOSEPOLICY_LAST /* last, never use this */ | ||||
| } curl_closepolicy; | ||||
|  | ||||
|  | ||||
| #ifdef  __cplusplus | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign | ||||
|  | ||||
| EXTRA_DIST = getdate.y \ | ||||
|        Makefile.b32 Makefile.b32.resp Makefile.m32 Makefile.vc6 \ | ||||
|        libcurl.def dllinit.c | ||||
|        libcurl.def dllinit.c curllib.dsp curllib.dsw | ||||
|  | ||||
| lib_LTLIBRARIES = libcurl.la | ||||
|  | ||||
| @@ -55,7 +55,7 @@ dict.c         ftp.h          if2ip.c        speedcheck.c   url.h \ | ||||
| dict.h         getdate.c      if2ip.h        speedcheck.h   urldata.h \ | ||||
| getdate.h      ldap.c         ssluse.c       version.c \ | ||||
| getenv.c       ldap.h         ssluse.h       \ | ||||
| escape.c       getenv.h       mprintf.c      telnet.c       \ | ||||
| escape.c       mprintf.c      telnet.c       \ | ||||
| escape.h       getpass.c      netrc.c        telnet.h       \ | ||||
| getinfo.c transfer.c strequal.c strequal.h easy.c \ | ||||
| security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h | ||||
|   | ||||
							
								
								
									
										367
									
								
								lib/curllib.dsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								lib/curllib.dsp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| # Microsoft Developer Studio Project File - Name="curllib" - Package Owner=<4> | ||||
| # Microsoft Developer Studio Generated Build File, Format Version 6.00 | ||||
| # ** DO NOT EDIT ** | ||||
|  | ||||
| # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 | ||||
|  | ||||
| CFG=curllib - Win32 Debug | ||||
| !MESSAGE This is not a valid makefile. To build this project using NMAKE, | ||||
| !MESSAGE use the Export Makefile command and run | ||||
| !MESSAGE  | ||||
| !MESSAGE NMAKE /f "curllib.mak". | ||||
| !MESSAGE  | ||||
| !MESSAGE You can specify a configuration when running NMAKE | ||||
| !MESSAGE by defining the macro CFG on the command line. For example: | ||||
| !MESSAGE  | ||||
| !MESSAGE NMAKE /f "curllib.mak" CFG="curllib - Win32 Debug" | ||||
| !MESSAGE  | ||||
| !MESSAGE Possible choices for configuration are: | ||||
| !MESSAGE  | ||||
| !MESSAGE "curllib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") | ||||
| !MESSAGE "curllib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") | ||||
| !MESSAGE  | ||||
|  | ||||
| # Begin Project | ||||
| # PROP AllowPerConfigDependencies 0 | ||||
| # PROP Scc_ProjName "" | ||||
| # PROP Scc_LocalPath "" | ||||
| CPP=cl.exe | ||||
| MTL=midl.exe | ||||
| RSC=rc.exe | ||||
|  | ||||
| !IF  "$(CFG)" == "curllib - Win32 Release" | ||||
|  | ||||
| # PROP BASE Use_MFC 0 | ||||
| # PROP BASE Use_Debug_Libraries 0 | ||||
| # PROP BASE Output_Dir "Release" | ||||
| # PROP BASE Intermediate_Dir "Release" | ||||
| # PROP BASE Target_Dir "" | ||||
| # PROP Use_MFC 0 | ||||
| # PROP Use_Debug_Libraries 0 | ||||
| # PROP Output_Dir "Release" | ||||
| # PROP Intermediate_Dir "Release" | ||||
| # PROP Ignore_Export_Lib 0 | ||||
| # PROP Target_Dir "" | ||||
| # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c | ||||
| # ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\jdk1.3.0_01\include" /I "C:\jdk1.3.0_01\include\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c | ||||
| # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 | ||||
| # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 | ||||
| # ADD BASE RSC /l 0x409 /d "NDEBUG" | ||||
| # ADD RSC /l 0x409 /d "NDEBUG" | ||||
| BSC32=bscmake.exe | ||||
| # ADD BASE BSC32 /nologo | ||||
| # ADD BSC32 /nologo | ||||
| LINK32=link.exe | ||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 | ||||
| # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /machine:I386 /out:"Release/curl.dll" | ||||
|  | ||||
| !ELSEIF  "$(CFG)" == "curllib - Win32 Debug" | ||||
|  | ||||
| # PROP BASE Use_MFC 0 | ||||
| # PROP BASE Use_Debug_Libraries 1 | ||||
| # PROP BASE Output_Dir "Debug" | ||||
| # PROP BASE Intermediate_Dir "Debug" | ||||
| # PROP BASE Target_Dir "" | ||||
| # PROP Use_MFC 0 | ||||
| # PROP Use_Debug_Libraries 1 | ||||
| # PROP Output_Dir "Debug" | ||||
| # PROP Intermediate_Dir "Debug" | ||||
| # PROP Ignore_Export_Lib 0 | ||||
| # PROP Target_Dir "" | ||||
| # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c | ||||
| # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\jdk1.3.0_01\include" /I "C:\jdk1.3.0_01\include\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c | ||||
| # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 | ||||
| # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 | ||||
| # ADD BASE RSC /l 0x409 /d "_DEBUG" | ||||
| # ADD RSC /l 0x409 /d "_DEBUG" | ||||
| BSC32=bscmake.exe | ||||
| # ADD BASE BSC32 /nologo | ||||
| # ADD BSC32 /nologo | ||||
| LINK32=link.exe | ||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept | ||||
| # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/curl.dll" /pdbtype:sept | ||||
|  | ||||
| !ENDIF  | ||||
|  | ||||
| # Begin Target | ||||
|  | ||||
| # Name "curllib - Win32 Release" | ||||
| # Name "curllib - Win32 Debug" | ||||
| # Begin Group "Source Files" | ||||
|  | ||||
| # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\base64.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\cookie.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\dict.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\dllinit.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\easy.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\easyswig.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\easyswig_wrap.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\escape.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\file.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\formdata.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\ftp.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getdate.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getenv.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getinfo.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getpass.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\hostip.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\http.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\if2ip.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\krb4.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\ldap.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\libcurl.def | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\memdebug.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\mprintf.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\netrc.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\progress.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\security.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\sendf.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\speedcheck.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\ssluse.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\strequal.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\telnet.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\timeval.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\transfer.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\url.c | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\version.c | ||||
| # End Source File | ||||
| # End Group | ||||
| # Begin Group "Header Files" | ||||
|  | ||||
| # PROP Default_Filter "h;hpp;hxx;hm;inl" | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\arpa_telnet.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\base64.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\cookie.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\dict.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\escape.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\file.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\formdata.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\ftp.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getdate.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getenv.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\getpass.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\hostip.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\http.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\if2ip.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\inet_ntoa_r.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\krb4.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\ldap.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\memdebug.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\netrc.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\progress.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\security.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\sendf.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\setup.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\speedcheck.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\ssluse.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\strequal.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\telnet.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\timeval.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\transfer.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\url.h | ||||
| # End Source File | ||||
| # Begin Source File | ||||
|  | ||||
| SOURCE=.\urldata.h | ||||
| # End Source File | ||||
| # End Group | ||||
| # Begin Group "Resource Files" | ||||
|  | ||||
| # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" | ||||
| # End Group | ||||
| # End Target | ||||
| # End Project | ||||
							
								
								
									
										29
									
								
								lib/curllib.dsw
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/curllib.dsw
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| Microsoft Developer Studio Workspace File, Format Version 6.00 | ||||
| # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! | ||||
|  | ||||
| ############################################################################### | ||||
|  | ||||
| Project: "curllib"=".\curllib.dsp" - Package Owner=<4> | ||||
|  | ||||
| Package=<5> | ||||
| {{{ | ||||
| }}} | ||||
|  | ||||
| Package=<4> | ||||
| {{{ | ||||
| }}} | ||||
|  | ||||
| ############################################################################### | ||||
|  | ||||
| Global: | ||||
|  | ||||
| Package=<5> | ||||
| {{{ | ||||
| }}} | ||||
|  | ||||
| Package=<3> | ||||
| {{{ | ||||
| }}} | ||||
|  | ||||
| ############################################################################### | ||||
|  | ||||
							
								
								
									
										12
									
								
								lib/dict.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								lib/dict.c
									
									
									
									
									
								
							| @@ -141,7 +141,7 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|       nth = atoi(nthdef); | ||||
|     } | ||||
|        | ||||
|     sendf(data->firstsocket, data, | ||||
|     Curl_sendf(conn->firstsocket, conn, | ||||
|                "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||
|                "MATCH " | ||||
|                "%s "    /* database */ | ||||
| @@ -154,7 +154,7 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|                word | ||||
|                ); | ||||
|      | ||||
|     result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount, | ||||
|     result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||
|                            -1, NULL); /* no upload */ | ||||
|        | ||||
|     if(result) | ||||
| @@ -191,7 +191,7 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|       nth = atoi(nthdef); | ||||
|     } | ||||
|        | ||||
|     sendf(data->firstsocket, data, | ||||
|     Curl_sendf(conn->firstsocket, conn, | ||||
|                "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||
|                "DEFINE " | ||||
|                "%s "     /* database */ | ||||
| @@ -202,7 +202,7 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|                word | ||||
|                ); | ||||
|      | ||||
|     result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount, | ||||
|     result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||
|                            -1, NULL); /* no upload */ | ||||
|      | ||||
|     if(result) | ||||
| @@ -220,13 +220,13 @@ CURLcode Curl_dict(struct connectdata *conn) | ||||
|         if (ppath[i] == ':') | ||||
|           ppath[i] = ' '; | ||||
|       } | ||||
|       sendf(data->firstsocket, data, | ||||
|       Curl_sendf(conn->firstsocket, conn, | ||||
|                  "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" | ||||
|                  "%s\n" | ||||
|                  "QUIT\n", | ||||
|                  ppath); | ||||
|        | ||||
|       result = Curl_Transfer(conn, data->firstsocket, -1, FALSE, bytecount, | ||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, FALSE, bytecount, | ||||
|                              -1, NULL); | ||||
|        | ||||
|       if(result) | ||||
|   | ||||
							
								
								
									
										577
									
								
								lib/ftp.c
									
									
									
									
									
								
							
							
						
						
									
										577
									
								
								lib/ftp.c
									
									
									
									
									
								
							| @@ -88,76 +88,8 @@ | ||||
| /* easy-to-use macro: */ | ||||
| #define ftpsendf Curl_ftpsendf | ||||
|  | ||||
| /* returns last node in linked list */ | ||||
| static struct curl_slist *slist_get_last(struct curl_slist *list) | ||||
| { | ||||
| 	struct curl_slist	*item; | ||||
|  | ||||
| 	/* if caller passed us a NULL, return now */ | ||||
| 	if (!list) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* loop through to find the last item */ | ||||
| 	item = list; | ||||
| 	while (item->next) { | ||||
| 		item = item->next; | ||||
| 	} | ||||
| 	return item; | ||||
| } | ||||
|  | ||||
| /* append a struct to the linked list. It always retunrs the address of the | ||||
|  * first record, so that you can sure this function as an initialization | ||||
|  * function as well as an append function. If you find this bothersome, | ||||
|  * then simply create a separate _init function and call it appropriately from | ||||
|  * within the proram. */ | ||||
| struct curl_slist *curl_slist_append(struct curl_slist *list, char *data) | ||||
| { | ||||
| 	struct curl_slist	*last; | ||||
| 	struct curl_slist	*new_item; | ||||
|  | ||||
| 	new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist)); | ||||
| 	if (new_item) { | ||||
| 		new_item->next = NULL; | ||||
| 		new_item->data = strdup(data); | ||||
| 	} | ||||
| 	else { | ||||
| 		fprintf(stderr, "Cannot allocate memory for QUOTE list.\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (list) { | ||||
| 		last = slist_get_last(list); | ||||
| 		last->next = new_item; | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	/* if this is the first item, then new_item *is* the list */ | ||||
| 	return new_item; | ||||
| } | ||||
|  | ||||
| /* be nice and clean up resources */ | ||||
| void curl_slist_free_all(struct curl_slist *list) | ||||
| { | ||||
| 	struct curl_slist	*next; | ||||
| 	struct curl_slist	*item; | ||||
|  | ||||
| 	if (!list) | ||||
| 		return; | ||||
|  | ||||
| 	item = list; | ||||
| 	do { | ||||
| 		next = item->next; | ||||
| 		 | ||||
| 		if (item->data) { | ||||
| 			free(item->data); | ||||
| 		} | ||||
| 		free(item); | ||||
| 		item = next; | ||||
| 	} while (next); | ||||
| } | ||||
|  | ||||
|  | ||||
| static CURLcode AllowServerConnect(struct UrlData *data, | ||||
|                                    struct connectdata *conn, | ||||
|                                    int sock) | ||||
| { | ||||
|   fd_set rdset; | ||||
| @@ -199,7 +131,7 @@ static CURLcode AllowServerConnect(struct UrlData *data, | ||||
|       } | ||||
|       infof(data, "Connection accepted from server\n"); | ||||
|  | ||||
|       data->secondarysocket = s; | ||||
|       conn->secondarysocket = s; | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
| @@ -221,7 +153,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf, | ||||
|                         int *ftpcode) | ||||
| { | ||||
|   int nread; | ||||
|   int keepon=TRUE; | ||||
|   ssize_t keepon=TRUE; | ||||
|   char *ptr; | ||||
|   int timeout = 3600; /* in seconds */ | ||||
|   struct timeval interval; | ||||
| @@ -272,22 +204,21 @@ int Curl_GetFTPResponse(int sockfd, char *buf, | ||||
|         break; | ||||
|       case 0: /* timeout */ | ||||
|         error = SELECT_TIMEOUT; | ||||
|         infof(data, "Transfer aborted due to timeout\n"); | ||||
|         failf(data, "Transfer aborted due to timeout"); | ||||
|         break; | ||||
|       default: | ||||
| #ifdef USE_SSLEAY | ||||
|         if (data->ssl.use) { | ||||
|           keepon = SSL_read(data->ssl.handle, ptr, 1); | ||||
|         /* | ||||
|          * This code previously didn't use the kerberos sec_read() code | ||||
|          * to read, but when we use Curl_read() it may do so. Do confirm | ||||
|          * that this is still ok and then remove this comment! | ||||
|          */ | ||||
|         if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon)) | ||||
|           keepon = FALSE; | ||||
|         else if(keepon <= 0) { | ||||
|           error = SELECT_ERROR; | ||||
|           failf(data, "Connection aborted"); | ||||
|         } | ||||
|         else { | ||||
| #endif | ||||
|           keepon = sread(sockfd, ptr, 1); | ||||
| #ifdef USE_SSLEAY | ||||
|         } | ||||
| #endif /* USE_SSLEAY */ | ||||
|  | ||||
|         if ((*ptr == '\n') || (*ptr == '\r')) | ||||
|         else if ((*ptr == '\n') || (*ptr == '\r')) | ||||
|           keepon = FALSE; | ||||
|       } | ||||
|       if(keepon) { | ||||
| @@ -363,23 +294,25 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
|   memset(ftp, 0, sizeof(struct FTP)); | ||||
|   data->proto.ftp = ftp; | ||||
|   conn->proto.ftp = ftp; | ||||
|  | ||||
|   /* get some initial data into the ftp struct */ | ||||
|   ftp->bytecountp = &conn->bytecount; | ||||
|   ftp->user = data->user; | ||||
|   ftp->passwd = data->passwd; | ||||
|  | ||||
|   /* duplicate to keep them even when the data struct changes */ | ||||
|   ftp->user = strdup(data->user); | ||||
|   ftp->passwd = strdup(data->passwd); | ||||
|  | ||||
|   if (data->bits.tunnel_thru_httpproxy) { | ||||
|     /* We want "seamless" FTP operations through HTTP proxy tunnel */ | ||||
|     result = Curl_ConnectHTTPProxyTunnel(data, data->firstsocket, | ||||
|                                          data->hostname, data->remote_port); | ||||
|     result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket, | ||||
|                                          conn->hostname, conn->remote_port); | ||||
|     if(CURLE_OK != result) | ||||
|       return result; | ||||
|   } | ||||
|  | ||||
|   /* The first thing we do is wait for the "220*" line: */ | ||||
|   nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|   if(nread < 0) | ||||
|     return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -399,7 +332,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) | ||||
|        set a valid level */ | ||||
|     sec_request_prot(conn, data->krb4_level); | ||||
|  | ||||
|     data->cmdchannel = fdopen(data->firstsocket, "w"); | ||||
|     data->cmdchannel = fdopen(conn->firstsocket, "w"); | ||||
|  | ||||
|     if(sec_login(conn) != 0) | ||||
|       infof(data, "Logging in with password in cleartext!\n"); | ||||
| @@ -409,10 +342,10 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) | ||||
| #endif | ||||
|    | ||||
|   /* send USER */ | ||||
|   ftpsendf(data->firstsocket, conn, "USER %s", ftp->user); | ||||
|   ftpsendf(conn->firstsocket, conn, "USER %s", ftp->user); | ||||
|  | ||||
|   /* wait for feedback */ | ||||
|   nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|   if(nread < 0) | ||||
|     return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -425,8 +358,8 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) | ||||
|   else if(ftpcode == 331) { | ||||
|     /* 331 Password required for ... | ||||
|        (the server requires to send the user's password too) */ | ||||
|     ftpsendf(data->firstsocket, conn, "PASS %s", ftp->passwd); | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     ftpsendf(conn->firstsocket, conn, "PASS %s", ftp->passwd); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -470,6 +403,58 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) | ||||
|     return CURLE_FTP_WEIRD_USER_REPLY; | ||||
|   } | ||||
|  | ||||
|   /* send PWD to discover our entry point */ | ||||
|   ftpsendf(conn->firstsocket, conn, "PWD"); | ||||
|  | ||||
|   /* wait for feedback */ | ||||
|   nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|   if(nread < 0) | ||||
|     return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
|   if(ftpcode == 257) { | ||||
|     char *dir = (char *)malloc(nread+1); | ||||
|     char *store=dir; | ||||
|     char *ptr=&buf[4]; /* start on the first letter */ | ||||
|      | ||||
|     /* Reply format is like | ||||
|        257<space>"<directory-name>"<space><commentary> and the RFC959 says | ||||
|  | ||||
|        The directory name can contain any character; embedded double-quotes | ||||
|        should be escaped by double-quotes (the "quote-doubling" convention). | ||||
|     */ | ||||
|     if('\"' == *ptr) { | ||||
|       /* it started good */ | ||||
|       ptr++; | ||||
|       while(ptr && *ptr) { | ||||
|         if('\"' == *ptr) { | ||||
|           if('\"' == ptr[1]) { | ||||
|             /* "quote-doubling" */ | ||||
|             *store = ptr[1]; | ||||
|             ptr++; | ||||
|           } | ||||
|           else { | ||||
|             /* end of path */ | ||||
|             *store = '\0'; /* zero terminate */ | ||||
|             break; /* get out of this loop */ | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|           *store = *ptr; | ||||
|         store++; | ||||
|         ptr++; | ||||
|       } | ||||
|       ftp->entrypath =dir; /* remember this */ | ||||
|       infof(data, "Entry path is '%s'\n", ftp->entrypath); | ||||
|     } | ||||
|     else { | ||||
|       /* couldn't get the path */ | ||||
|     } | ||||
|  | ||||
|   } | ||||
|   else { | ||||
|     /* We couldn't read the PWD response! */ | ||||
|   } | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| @@ -478,7 +463,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) | ||||
| CURLcode Curl_ftp_done(struct connectdata *conn) | ||||
| { | ||||
|   struct UrlData *data = conn->data; | ||||
|   struct FTP *ftp = data->proto.ftp; | ||||
|   struct FTP *ftp = conn->proto.ftp; | ||||
|   size_t nread; | ||||
|   char *buf = data->buffer; /* this is our buffer */ | ||||
|   struct curl_slist *qitem; /* QUOTE item */ | ||||
| @@ -493,7 +478,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn) | ||||
|   } | ||||
|   else { | ||||
|     if((-1 != conn->size) && (conn->size != *ftp->bytecountp) && | ||||
|        (data->maxdownload != *ftp->bytecountp)) { | ||||
|        (conn->maxdownload != *ftp->bytecountp)) { | ||||
|       failf(data, "Received only partial file"); | ||||
|       return CURLE_PARTIAL_FILE; | ||||
|     } | ||||
| @@ -503,16 +488,16 @@ CURLcode Curl_ftp_done(struct connectdata *conn) | ||||
|     } | ||||
|   } | ||||
| #ifdef KRB4 | ||||
|   sec_fflush_fd(conn, data->secondarysocket); | ||||
|   sec_fflush_fd(conn, conn->secondarysocket); | ||||
| #endif | ||||
|   /* shut down the socket to inform the server we're done */ | ||||
|   sclose(data->secondarysocket); | ||||
|   data->secondarysocket = -1; | ||||
|   sclose(conn->secondarysocket); | ||||
|   conn->secondarysocket = -1; | ||||
|  | ||||
|   if(!data->bits.no_body) {   | ||||
|     /* now let's see what the server says about the transfer we | ||||
|        just performed: */ | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -530,9 +515,9 @@ CURLcode Curl_ftp_done(struct connectdata *conn) | ||||
|     while (qitem) { | ||||
|       /* Send string */ | ||||
|       if (qitem->data) { | ||||
|         ftpsendf(data->firstsocket, conn, "%s", qitem->data); | ||||
|         ftpsendf(conn->firstsocket, conn, "%s", qitem->data); | ||||
|  | ||||
|         nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|         nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|         if(nread < 0) | ||||
|           return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -546,9 +531,6 @@ CURLcode Curl_ftp_done(struct connectdata *conn) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   free(ftp); | ||||
|   data->proto.ftp=NULL; /* it is gone */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| @@ -569,10 +551,13 @@ CURLcode _ftp(struct connectdata *conn) | ||||
| #if defined (HAVE_INET_NTOA_R) | ||||
|   char ntoa_buf[64]; | ||||
| #endif | ||||
| #ifdef ENABLE_IPV6 | ||||
|   struct addrinfo *ai; | ||||
| #endif | ||||
|  | ||||
|   struct curl_slist *qitem; /* QUOTE item */ | ||||
|   /* the ftp struct is already inited in ftp_connect() */ | ||||
|   struct FTP *ftp = data->proto.ftp; | ||||
|   struct FTP *ftp = conn->proto.ftp; | ||||
|  | ||||
|   long *bytecountp = ftp->bytecountp; | ||||
|   int ftpcode; /* for ftp status */ | ||||
| @@ -584,9 +569,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|     while (qitem) { | ||||
|       /* Send string */ | ||||
|       if (qitem->data) { | ||||
|         ftpsendf(data->firstsocket, conn, "%s", qitem->data); | ||||
|         ftpsendf(conn->firstsocket, conn, "%s", qitem->data); | ||||
|  | ||||
|         nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|         nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|         if(nread < 0) | ||||
|           return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -600,10 +585,27 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if(conn->bits.reuse) { | ||||
|     /* This is a re-used connection. Since we change directory to where the | ||||
|        transfer is taking place, we must now get back to the original dir | ||||
|        where we ended up after login: */ | ||||
|     ftpsendf(conn->firstsocket, conn, "CWD %s", ftp->entrypath); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|      | ||||
|     if(ftpcode != 250) { | ||||
|       failf(data, "Couldn't change back to directory %s", ftp->entrypath); | ||||
|       return CURLE_FTP_ACCESS_DENIED; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   /* change directory first! */ | ||||
|   if(ftp->dir && ftp->dir[0]) { | ||||
|     ftpsendf(data->firstsocket, conn, "CWD %s", ftp->dir); | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     ftpsendf(conn->firstsocket, conn, "CWD %s", ftp->dir); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -616,9 +618,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|   if(data->bits.get_filetime && ftp->file) { | ||||
|     /* we have requested to get the modified-time of the file, this is yet | ||||
|        again a grey area as the MDTM is not kosher RFC959 */ | ||||
|     ftpsendf(data->firstsocket, conn, "MDTM %s", ftp->file); | ||||
|     ftpsendf(conn->firstsocket, conn, "MDTM %s", ftp->file); | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -652,10 +654,10 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|  | ||||
|     /* Some servers return different sizes for different modes, and thus we | ||||
|        must set the proper type before we check the size */ | ||||
|     ftpsendf(data->firstsocket, conn, "TYPE %s", | ||||
|     ftpsendf(conn->firstsocket, conn, "TYPE %s", | ||||
|              (data->bits.ftp_ascii)?"A":"I"); | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -666,9 +668,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         CURLE_FTP_COULDNT_SET_BINARY; | ||||
|     } | ||||
|  | ||||
|     ftpsendf(data->firstsocket, conn, "SIZE %s", ftp->file); | ||||
|     ftpsendf(conn->firstsocket, conn, "SIZE %s", ftp->file); | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -707,6 +709,178 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|  | ||||
|   /* We have chosen to use the PORT command */ | ||||
|   if(data->bits.ftp_use_port) { | ||||
| #ifdef ENABLE_IPV6 | ||||
|     struct addrinfo hints, *res, *ai; | ||||
|     struct sockaddr_storage ss; | ||||
|     int sslen; | ||||
|     char hbuf[NI_MAXHOST]; | ||||
|     char *localaddr; | ||||
|     struct sockaddr *sa=(struct sockaddr *)&ss; | ||||
| #ifdef NI_WITHSCOPEID | ||||
|     const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; | ||||
| #else | ||||
|     const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; | ||||
| #endif | ||||
|     unsigned char *ap; | ||||
|     unsigned char *pp; | ||||
|     int alen, plen; | ||||
|     char portmsgbuf[4096], tmp[4096]; | ||||
|     char *p; | ||||
|     char *mode[] = { "EPRT", "LPRT", "PORT", NULL }; | ||||
|     char **modep; | ||||
|  | ||||
|     /* | ||||
|      * we should use Curl_if2ip?  given pickiness of recent ftpd, | ||||
|      * I believe we should use the same address as the control connection. | ||||
|      */ | ||||
|     sslen = sizeof(ss); | ||||
|     if (getsockname(conn->firstsocket, (struct sockaddr *)&ss, &sslen) < 0) | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|  | ||||
|     if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0, | ||||
| 	niflags)) | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|  | ||||
|     memset(&hints, 0, sizeof(hints)); | ||||
|     hints.ai_family = sa->sa_family; | ||||
|     /*hints.ai_family = ss.ss_family; | ||||
|       this way can be used if sockaddr_storage is properly defined, as glibc  | ||||
|       2.1.X doesn't do*/ | ||||
|     hints.ai_socktype = SOCK_STREAM; | ||||
|     hints.ai_flags = AI_PASSIVE; | ||||
|     if (getaddrinfo(hbuf, "0", &hints, &res)) | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|  | ||||
|     portsock = -1; | ||||
|     for (ai = res; ai; ai = ai->ai_next) { | ||||
|       portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | ||||
|       if (portsock < 0) | ||||
| 	continue; | ||||
|  | ||||
|       if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) { | ||||
| 	close(portsock); | ||||
| 	portsock = -1; | ||||
| 	continue; | ||||
|       } | ||||
|  | ||||
|       if (listen(portsock, 1) < 0) { | ||||
| 	close(portsock); | ||||
| 	portsock = -1; | ||||
| 	continue; | ||||
|       } | ||||
|  | ||||
|       break; | ||||
|     } | ||||
|     if (portsock < 0) { | ||||
|       failf(data, strerror(errno)); | ||||
|       freeaddrinfo(res); | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|     } | ||||
|  | ||||
|     sslen = sizeof(ss); | ||||
|     if (getsockname(portsock, sa, &sslen) < 0) { | ||||
|       failf(data, strerror(errno)); | ||||
|       freeaddrinfo(res); | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|     } | ||||
|  | ||||
|     for (modep = mode; modep && *modep; modep++) { | ||||
|       int lprtaf, eprtaf; | ||||
|  | ||||
|       switch (sa->sa_family) { | ||||
|       case AF_INET: | ||||
| 	ap = (char *)&((struct sockaddr_in *)&ss)->sin_addr; | ||||
| 	alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr); | ||||
| 	pp = (char *)&((struct sockaddr_in *)&ss)->sin_port; | ||||
| 	plen = sizeof(((struct sockaddr_in *)&ss)->sin_port); | ||||
| 	lprtaf = 4; | ||||
| 	eprtaf = 1; | ||||
| 	break; | ||||
|       case AF_INET6: | ||||
| 	ap = (char *)&((struct sockaddr_in6 *)&ss)->sin6_addr; | ||||
| 	alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr); | ||||
| 	pp = (char *)&((struct sockaddr_in6 *)&ss)->sin6_port; | ||||
| 	plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port); | ||||
| 	lprtaf = 6; | ||||
| 	eprtaf = 2; | ||||
| 	break; | ||||
|       default: | ||||
| 	ap = pp = NULL; | ||||
| 	lprtaf = eprtaf = -1; | ||||
| 	break; | ||||
|       } | ||||
|  | ||||
|       if (strcmp(*modep, "EPRT") == 0) { | ||||
| 	if (eprtaf < 0) | ||||
| 	  continue; | ||||
| 	if (getnameinfo((struct sockaddr *)&ss, sslen, | ||||
| 	    portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags)) | ||||
| 	  continue; | ||||
| 	/* do not transmit IPv6 scope identifier to the wire */ | ||||
| 	if (sa->sa_family == AF_INET6) { | ||||
| 	  char *q = strchr(portmsgbuf, '%'); | ||||
| 	  if (q) | ||||
| 	    *q = '\0'; | ||||
| 	} | ||||
| 	ftpsendf(conn->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf, | ||||
| 	    portmsgbuf, tmp); | ||||
|       } else if (strcmp(*modep, "LPRT") == 0 || strcmp(*modep, "PORT") == 0) { | ||||
| 	int i; | ||||
|  | ||||
|         if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0) | ||||
| 	  continue; | ||||
|         if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET) | ||||
| 	  continue; | ||||
|  | ||||
| 	portmsgbuf[0] = '\0'; | ||||
|         if (strcmp(*modep, "LPRT") == 0) { | ||||
| 	  snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen); | ||||
| 	  if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) { | ||||
| 	    goto again; | ||||
| 	  } | ||||
| 	} | ||||
| 	for (i = 0; i < alen; i++) { | ||||
| 	  if (portmsgbuf[0]) | ||||
| 	    snprintf(tmp, sizeof(tmp), ",%u", ap[i]); | ||||
| 	  else | ||||
| 	    snprintf(tmp, sizeof(tmp), "%u", ap[i]); | ||||
| 	  if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) { | ||||
| 	    goto again; | ||||
| 	  } | ||||
| 	} | ||||
|         if (strcmp(*modep, "LPRT") == 0) { | ||||
| 	  snprintf(tmp, sizeof(tmp), ",%d", plen); | ||||
| 	  if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) | ||||
| 	    goto again; | ||||
| 	} | ||||
| 	for (i = 0; i < plen; i++) { | ||||
| 	  snprintf(tmp, sizeof(tmp), ",%u", pp[i]); | ||||
| 	  if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) { | ||||
| 	    goto again; | ||||
| 	  } | ||||
| 	} | ||||
| 	ftpsendf(conn->firstsocket, conn, "%s %s", *modep, portmsgbuf); | ||||
|       } | ||||
|  | ||||
|       nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|       if (nread < 0) | ||||
| 	return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
|       if (ftpcode != 200) { | ||||
| 	failf(data, "Server does not grok %s", *modep); | ||||
| 	continue; | ||||
|       } else | ||||
| 	      break; | ||||
| again:; | ||||
|     } | ||||
|  | ||||
|     if (!*modep) { | ||||
|       close(portsock); | ||||
|       freeaddrinfo(res); | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|     } | ||||
|  | ||||
| #else | ||||
|     struct sockaddr_in sa; | ||||
|     struct hostent *h=NULL; | ||||
|     char *hostdataptr=NULL; | ||||
| @@ -738,7 +912,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         /* we set the secondary socket variable to this for now, it | ||||
|            is only so that the cleanup function will close it in case | ||||
|            we fail before the true secondary stuff is made */ | ||||
|         data->secondarysocket = portsock; | ||||
|         conn->secondarysocket = portsock; | ||||
|  | ||||
|         memset((char *)&sa, 0, sizeof(sa)); | ||||
|         memcpy((char *)&sa.sin_addr, | ||||
| @@ -800,13 +974,13 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|       sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu", | ||||
|               &ip[0], &ip[1], &ip[2], &ip[3]); | ||||
| #endif | ||||
|       ftpsendf(data->firstsocket, conn, "PORT %d,%d,%d,%d,%d,%d", | ||||
|       ftpsendf(conn->firstsocket, conn, "PORT %d,%d,%d,%d,%d,%d", | ||||
|             ip[0], ip[1], ip[2], ip[3], | ||||
|             porttouse >> 8, | ||||
|             porttouse & 255); | ||||
|     } | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -814,26 +988,43 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|       failf(data, "Server does not grok PORT, try without it!"); | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|     }      | ||||
| #endif /* ENABLE_IPV6 */ | ||||
|   } | ||||
|   else { /* we use the PASV command */ | ||||
| #if 0 | ||||
|     char *mode[] = { "EPSV", "LPSV", "PASV", NULL }; | ||||
|     int results[] = { 229, 228, 227, 0 }; | ||||
| #else | ||||
|     char *mode[] = { "PASV", NULL }; | ||||
|     int results[] = { 227, 0 }; | ||||
| #endif | ||||
|     int modeoff; | ||||
|  | ||||
|     ftpsendf(data->firstsocket, conn, "PASV"); | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     for (modeoff = 0; mode[modeoff]; modeoff++) { | ||||
|       ftpsendf(conn->firstsocket, conn, mode[modeoff]); | ||||
|       nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|       if(nread < 0) | ||||
| 	return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
|     if(ftpcode != 227) { | ||||
|       if (ftpcode == results[modeoff]) | ||||
| 	break; | ||||
|     } | ||||
|  | ||||
|     if (!mode[modeoff]) { | ||||
|       failf(data, "Odd return code after PASV"); | ||||
|       return CURLE_FTP_WEIRD_PASV_REPLY; | ||||
|     } | ||||
|     else { | ||||
|     else if (strcmp(mode[modeoff], "PASV") == 0) { | ||||
|       int ip[4]; | ||||
|       int port[2]; | ||||
|       unsigned short newport; /* remote port, not necessary the local one */ | ||||
|       unsigned short connectport; /* the local port connect() should use! */ | ||||
|       char newhost[32]; | ||||
| #ifdef ENABLE_IPV6 | ||||
|       struct addrinfo *res; | ||||
| #else | ||||
|       struct hostent *he; | ||||
| #endif | ||||
|       char *str=buf,*ip_addr; | ||||
|       char *hostdataptr=NULL; | ||||
|  | ||||
| @@ -868,21 +1059,79 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|          * proxy again here. We already have the name info for it since the | ||||
|          * previous lookup. | ||||
|          */ | ||||
| #ifdef ENABLE_IPV6 | ||||
|         res = conn->hp; | ||||
| #else | ||||
|         he = conn->hp; | ||||
| #endif | ||||
|         connectport = | ||||
|           (unsigned short)data->port; /* we connect to the proxy's port */ | ||||
|           (unsigned short)conn->port; /* we connect to the proxy's port */ | ||||
|       } | ||||
|       else { | ||||
|         /* normal, direct, ftp connection */ | ||||
| #ifdef ENABLE_IPV6 | ||||
|         res = Curl_getaddrinfo(data, newhost, newport); | ||||
|         if(!res) | ||||
| #else | ||||
|         he = Curl_gethost(data, newhost, &hostdataptr); | ||||
|         if(!he) { | ||||
|         if(!he) | ||||
| #endif | ||||
|         { | ||||
|           failf(data, "Can't resolve new host %s", newhost); | ||||
|           return CURLE_FTP_CANT_GET_HOST; | ||||
|         } | ||||
|         connectport = newport; /* we connect to the remote port */ | ||||
|       } | ||||
| 	 | ||||
|       data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
| #ifdef ENABLE_IPV6 | ||||
|       conn->secondarysocket = -1; | ||||
|       for (ai = res; ai; ai = ai->ai_next) { | ||||
| 	/* XXX for now, we can do IPv4 only */ | ||||
| 	if (ai->ai_family != AF_INET) | ||||
| 	  continue; | ||||
|  | ||||
| 	conn->secondarysocket = socket(ai->ai_family, ai->ai_socktype, | ||||
| 	    ai->ai_protocol); | ||||
| 	if (conn->secondarysocket < 0) | ||||
| 	  continue; | ||||
|  | ||||
| 	if(data->bits.verbose) { | ||||
| 	  char hbuf[NI_MAXHOST]; | ||||
| 	  char nbuf[NI_MAXHOST]; | ||||
| 	  char sbuf[NI_MAXSERV]; | ||||
| #ifdef NI_WITHSCOPEID | ||||
| 	  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; | ||||
| #else | ||||
| 	  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; | ||||
| #endif | ||||
| 	  if (getnameinfo(res->ai_addr, res->ai_addrlen, nbuf, sizeof(nbuf), | ||||
| 	      sbuf, sizeof(sbuf), niflags)) { | ||||
| 	    snprintf(nbuf, sizeof(nbuf), "?"); | ||||
| 	    snprintf(sbuf, sizeof(sbuf), "?"); | ||||
| 	  } | ||||
| 	  if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), | ||||
| 	      NULL, 0, 0)) { | ||||
| 	    infof(data, "Connecting to %s port %s\n", nbuf, sbuf); | ||||
| 	  } else { | ||||
| 	    infof(data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf); | ||||
| 	  } | ||||
| 	} | ||||
|  | ||||
| 	if (connect(conn->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) { | ||||
| 	  close(conn->secondarysocket); | ||||
| 	  conn->secondarysocket = -1; | ||||
| 	  continue; | ||||
| 	} | ||||
|  | ||||
| 	break; | ||||
|       } | ||||
|  | ||||
|       if (conn->secondarysocket < 0) { | ||||
| 	failf(data, strerror(errno)); | ||||
|         return CURLE_FTP_CANT_RECONNECT; | ||||
|       } | ||||
| #else | ||||
|       conn->secondarysocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
|  | ||||
|       memset((char *) &serv_addr, '\0', sizeof(serv_addr)); | ||||
|       memcpy((char *)&(serv_addr.sin_addr), he->h_addr, he->h_length); | ||||
| @@ -956,7 +1205,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|       if(hostdataptr) | ||||
|         free(hostdataptr); | ||||
|  | ||||
|       if (connect(data->secondarysocket, (struct sockaddr *) &serv_addr, | ||||
|       if (connect(conn->secondarysocket, (struct sockaddr *) &serv_addr, | ||||
|                   sizeof(serv_addr)) < 0) { | ||||
|         switch(errno) { | ||||
| #ifdef ECONNREFUSED | ||||
| @@ -967,7 +1216,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
| #endif | ||||
| #ifdef EINTR | ||||
|         case EINTR: | ||||
|           failf(data, "Connection timeouted to ftp server"); | ||||
|           failf(data, "Connection timed out to ftp server"); | ||||
|           break; | ||||
| #endif | ||||
|         default: | ||||
| @@ -976,14 +1225,17 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         } | ||||
|         return CURLE_FTP_CANT_RECONNECT; | ||||
|       } | ||||
| #endif /*ENABLE_IPV6*/ | ||||
|  | ||||
|       if (data->bits.tunnel_thru_httpproxy) { | ||||
|         /* We want "seamless" FTP operations through HTTP proxy tunnel */ | ||||
|         result = Curl_ConnectHTTPProxyTunnel(data, data->secondarysocket, | ||||
|         result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket, | ||||
|                                              newhost, newport); | ||||
|         if(CURLE_OK != result) | ||||
|           return result; | ||||
|       } | ||||
|     } else { | ||||
|       return CURLE_FTP_CANT_RECONNECT; | ||||
|     } | ||||
|   } | ||||
|   /* we have the (new) data connection ready */ | ||||
| @@ -992,10 +1244,10 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|   if(data->bits.upload) { | ||||
|  | ||||
|     /* Set type to binary (unless specified ASCII) */ | ||||
|     ftpsendf(data->firstsocket, conn, "TYPE %s", | ||||
|     ftpsendf(conn->firstsocket, conn, "TYPE %s", | ||||
|           (data->bits.ftp_ascii)?"A":"I"); | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1024,9 +1276,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         /* we could've got a specified offset from the command line, | ||||
|            but now we know we didn't */ | ||||
|  | ||||
|         ftpsendf(data->firstsocket, conn, "SIZE %s", ftp->file); | ||||
|         ftpsendf(conn->firstsocket, conn, "SIZE %s", ftp->file); | ||||
|  | ||||
|         nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|         nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|         if(nread < 0) | ||||
|           return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1083,11 +1335,11 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|     /* Send everything on data->in to the socket */ | ||||
|     if(data->bits.ftp_append) | ||||
|       /* we append onto the file instead of rewriting it */ | ||||
|       ftpsendf(data->firstsocket, conn, "APPE %s", ftp->file); | ||||
|       ftpsendf(conn->firstsocket, conn, "APPE %s", ftp->file); | ||||
|     else | ||||
|       ftpsendf(data->firstsocket, conn, "STOR %s", ftp->file); | ||||
|       ftpsendf(conn->firstsocket, conn, "STOR %s", ftp->file); | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1098,7 +1350,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|     } | ||||
|  | ||||
|     if(data->bits.ftp_use_port) { | ||||
|       result = AllowServerConnect(data, portsock); | ||||
|       result = AllowServerConnect(data, conn, portsock); | ||||
|       if( result ) | ||||
|         return result; | ||||
|     } | ||||
| @@ -1111,7 +1363,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|     Curl_pgrsSetUploadSize(data, data->infilesize); | ||||
|  | ||||
|     result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ | ||||
|                       data->secondarysocket, bytecountp); | ||||
|                       conn->secondarysocket, bytecountp); | ||||
|     if(result) | ||||
|       return result; | ||||
|        | ||||
| @@ -1143,16 +1395,16 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|       else if(from < 0) { | ||||
|         /* -Y */ | ||||
|         totalsize = -from; | ||||
|         data->maxdownload = -from; | ||||
|         conn->maxdownload = -from; | ||||
|         data->resume_from = from; | ||||
|         infof(data, "FTP RANGE the last %d bytes\n", totalsize); | ||||
|       } | ||||
|       else { | ||||
|         /* X-Y */ | ||||
|         totalsize = to-from; | ||||
|         data->maxdownload = totalsize+1; /* include the last mentioned byte */ | ||||
|         conn->maxdownload = totalsize+1; /* include the last mentioned byte */ | ||||
|         data->resume_from = from; | ||||
|         infof(data, "FTP RANGE from %d getting %d bytes\n", from, data->maxdownload); | ||||
|         infof(data, "FTP RANGE from %d getting %d bytes\n", from, conn->maxdownload); | ||||
|       } | ||||
|       infof(data, "range-download from %d to %d, totally %d bytes\n", | ||||
|             from, to, totalsize); | ||||
| @@ -1165,9 +1417,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|       dirlist = TRUE; | ||||
|  | ||||
|       /* Set type to ASCII */ | ||||
|       ftpsendf(data->firstsocket, conn, "TYPE A"); | ||||
|       ftpsendf(conn->firstsocket, conn, "TYPE A"); | ||||
| 	 | ||||
|       nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|       nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|       if(nread < 0) | ||||
|         return CURLE_OPERATION_TIMEOUTED; | ||||
| 	 | ||||
| @@ -1180,16 +1432,16 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|          better used since the LIST command output is not specified or | ||||
|          standard in any way */ | ||||
|  | ||||
|       ftpsendf(data->firstsocket, conn, "%s", | ||||
|       ftpsendf(conn->firstsocket, conn, "%s", | ||||
|             data->customrequest?data->customrequest: | ||||
|             (data->bits.ftp_list_only?"NLST":"LIST")); | ||||
|     } | ||||
|     else { | ||||
|       /* Set type to binary (unless specified ASCII) */ | ||||
|       ftpsendf(data->firstsocket, conn, "TYPE %s", | ||||
|       ftpsendf(conn->firstsocket, conn, "TYPE %s", | ||||
|                (data->bits.ftp_ascii)?"A":"I"); | ||||
|  | ||||
|       nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|       nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|       if(nread < 0) | ||||
|         return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1208,9 +1460,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|          * of the file we're gonna get. If we can get the size, this is by far | ||||
|          * the best way to know if we're trying to resume beyond the EOF.  */ | ||||
|  | ||||
|         ftpsendf(data->firstsocket, conn, "SIZE %s", ftp->file); | ||||
|         ftpsendf(conn->firstsocket, conn, "SIZE %s", ftp->file); | ||||
|  | ||||
|         nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|         nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|         if(nread < 0) | ||||
|           return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1252,9 +1504,9 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         infof(data, "Instructs server to resume from offset %d\n", | ||||
|               data->resume_from); | ||||
|  | ||||
|         ftpsendf(data->firstsocket, conn, "REST %d", data->resume_from); | ||||
|         ftpsendf(conn->firstsocket, conn, "REST %d", data->resume_from); | ||||
|  | ||||
|         nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|         nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|         if(nread < 0) | ||||
|           return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1264,10 +1516,10 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       ftpsendf(data->firstsocket, conn, "RETR %s", ftp->file); | ||||
|       ftpsendf(conn->firstsocket, conn, "RETR %s", ftp->file); | ||||
|     } | ||||
|  | ||||
|     nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode); | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); | ||||
|     if(nread < 0) | ||||
|       return CURLE_OPERATION_TIMEOUTED; | ||||
|  | ||||
| @@ -1331,7 +1583,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|         size = downloadsize; | ||||
|  | ||||
|       if(data->bits.ftp_use_port) { | ||||
|         result = AllowServerConnect(data, portsock); | ||||
|         result = AllowServerConnect(data, conn, portsock); | ||||
|         if( result ) | ||||
|           return result; | ||||
|       } | ||||
| @@ -1339,7 +1591,7 @@ CURLcode _ftp(struct connectdata *conn) | ||||
|       infof(data, "Getting file with size: %d\n", size); | ||||
|  | ||||
|       /* FTP download: */ | ||||
|       result=Curl_Transfer(conn, data->secondarysocket, size, FALSE, | ||||
|       result=Curl_Transfer(conn, conn->secondarysocket, size, FALSE, | ||||
|                       bytecountp, | ||||
|                       -1, NULL); /* no upload here */ | ||||
|       if(result) | ||||
| @@ -1368,7 +1620,7 @@ CURLcode Curl_ftp(struct connectdata *conn) | ||||
|   int dirlength=0; /* 0 forces strlen() */ | ||||
|  | ||||
|   /* the ftp struct is already inited in ftp_connect() */ | ||||
|   ftp = data->proto.ftp; | ||||
|   ftp = conn->proto.ftp; | ||||
|  | ||||
|   /* We split the path into dir and file parts *before* we URLdecode | ||||
|      it */ | ||||
| @@ -1457,3 +1709,16 @@ size_t Curl_ftpsendf(int fd, struct connectdata *conn, char *fmt, ...) | ||||
| } | ||||
|  | ||||
|  | ||||
| CURLcode Curl_ftp_disconnect(struct connectdata *conn) | ||||
| { | ||||
|   struct FTP *ftp= conn->proto.ftp; | ||||
|  | ||||
|   if(ftp->user) | ||||
|     free(ftp->user); | ||||
|   if(ftp->passwd) | ||||
|     free(ftp->passwd); | ||||
|   if(ftp->entrypath) | ||||
|     free(ftp->entrypath); | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|   | ||||
| @@ -26,12 +26,10 @@ | ||||
| CURLcode Curl_ftp(struct connectdata *conn); | ||||
| CURLcode Curl_ftp_done(struct connectdata *conn); | ||||
| CURLcode Curl_ftp_connect(struct connectdata *conn); | ||||
| CURLcode Curl_ftp_disconnect(struct connectdata *conn); | ||||
|  | ||||
| size_t Curl_ftpsendf(int fd, struct connectdata *, char *fmt, ...); | ||||
|  | ||||
| struct curl_slist *curl_slist_append(struct curl_slist *list, char *data); | ||||
| void curl_slist_free_all(struct curl_slist *list); | ||||
|  | ||||
| /* The kerberos stuff needs this: */ | ||||
| int Curl_GetFTPResponse(int sockfd, char *buf, | ||||
|                         struct connectdata *conn, | ||||
|   | ||||
| @@ -390,7 +390,7 @@ static const short yycheck[] = {     0, | ||||
|     56 | ||||
| }; | ||||
| /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */ | ||||
| #line 3 "/usr/local/share/bison.simple" | ||||
| #line 3 "/usr/lib/bison.simple" | ||||
| /* This file comes from bison-1.28.  */ | ||||
|  | ||||
| /* Skeleton output parser for bison, | ||||
| @@ -604,7 +604,7 @@ __yy_memcpy (char *to, char *from, unsigned int count) | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #line 217 "/usr/local/share/bison.simple" | ||||
| #line 217 "/usr/lib/bison.simple" | ||||
|  | ||||
| /* The user can define YYPARSE_PARAM as the name of an argument to be passed | ||||
|    into yyparse.  The argument should have type void *. | ||||
| @@ -1295,7 +1295,7 @@ case 50: | ||||
|     break;} | ||||
| } | ||||
|    /* the action file gets copied in in place of this dollarsign */ | ||||
| #line 543 "/usr/local/share/bison.simple" | ||||
| #line 543 "/usr/lib/bison.simple" | ||||
|  | ||||
|   yyvsp -= yylen; | ||||
|   yyssp -= yylen; | ||||
|   | ||||
| @@ -41,12 +41,13 @@ char *GetEnv(char *variable) | ||||
|   char env[MAX_PATH]; /* MAX_PATH is from windef.h */ | ||||
|   char *temp = getenv(variable); | ||||
|   env[0] = '\0'; | ||||
|   if (temp != NULL) | ||||
|     ExpandEnvironmentStrings(temp, env, sizeof(env)); | ||||
| #else | ||||
|   /* no length control */ | ||||
|   char *env = getenv(variable); | ||||
| #endif | ||||
|   return env?strdup(env):NULL; | ||||
|   return (env && env[0])?strdup(env):NULL; | ||||
| } | ||||
|  | ||||
| char *curl_getenv(char *v) | ||||
|   | ||||
							
								
								
									
										28
									
								
								lib/getenv.h
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								lib/getenv.h
									
									
									
									
									
								
							| @@ -1,28 +0,0 @@ | ||||
| #ifndef __GETENV_H | ||||
| #define __GETENV_H | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _      | ||||
|  *  Project                     ___| | | |  _ \| |     | ||||
|  *                             / __| | | | |_) | |     | ||||
|  *                            | (__| |_| |  _ <| |___  | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 2000, 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> | ||||
|  | ||||
| #endif | ||||
| @@ -103,6 +103,12 @@ CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...) | ||||
|   case CURLINFO_SSL_VERIFYRESULT: | ||||
|     *param_longp = data->ssl.certverifyresult; | ||||
|     break; | ||||
|   case CURLINFO_CONTENT_LENGTH_DOWNLOAD: | ||||
|     *param_doublep = data->progress.size_dl; | ||||
|     break; | ||||
|   case CURLINFO_CONTENT_LENGTH_UPLOAD: | ||||
|     *param_doublep = data->progress.size_ul; | ||||
|     break; | ||||
|   default: | ||||
|     return CURLE_BAD_FUNCTION_ARGUMENT; | ||||
|   } | ||||
|   | ||||
							
								
								
									
										23
									
								
								lib/hostip.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								lib/hostip.c
									
									
									
									
									
								
							| @@ -83,6 +83,29 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len) | ||||
|   return (addr); | ||||
| } | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
| struct addrinfo *Curl_getaddrinfo(struct UrlData *data, | ||||
| 			       char *hostname, | ||||
| 			       int port) | ||||
| { | ||||
|   struct addrinfo hints, *res; | ||||
|   int error; | ||||
|   char sbuf[NI_MAXSERV]; | ||||
|  | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = PF_UNSPEC; | ||||
|   hints.ai_socktype = SOCK_STREAM; | ||||
|   hints.ai_flags = AI_CANONNAME; | ||||
|   snprintf(sbuf, sizeof(sbuf), "%d", port); | ||||
|   error = getaddrinfo(hostname, sbuf, &hints, &res); | ||||
|   if (error) { | ||||
|     infof(data, "getaddrinfo(3) failed for %s\n", hostname); | ||||
|     return NULL; | ||||
|   } | ||||
|   return res; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* The original code to this function was once stolen from the Dancer source | ||||
|    code, written by Bjorn Reese, it has since been patched and modified | ||||
|    considerably. */ | ||||
|   | ||||
| @@ -23,6 +23,11 @@ | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| struct addrinfo; | ||||
| struct addrinfo *Curl_getaddrinfo(struct UrlData *data, | ||||
|                              char *hostname, | ||||
|                              int port); | ||||
|  | ||||
| struct hostent *Curl_gethost(struct UrlData *data, | ||||
|                              char *hostname, | ||||
|                              char **bufp); | ||||
|   | ||||
							
								
								
									
										216
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								lib/http.c
									
									
									
									
									
								
							| @@ -94,7 +94,6 @@ | ||||
| #include "base64.h" | ||||
| #include "cookie.h" | ||||
| #include "strequal.h" | ||||
| #include "url.h" | ||||
| #include "ssluse.h" | ||||
|  | ||||
| #define _MPRINTF_REPLACE /* use our functions only */ | ||||
| @@ -141,7 +140,7 @@ size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in) | ||||
|     fwrite(in->buffer, in->size_used, 1, conn->data->err); | ||||
|   } | ||||
|  | ||||
|   amount = ssend(sockfd, conn, in->buffer, in->size_used); | ||||
|   Curl_write(conn, sockfd, in->buffer, in->size_used, &amount); | ||||
|  | ||||
|   if(in->buffer) | ||||
|     free(in->buffer); | ||||
| @@ -213,28 +212,22 @@ CURLcode add_buffer(send_buffer *in, void *inptr, size_t size) | ||||
|  */ | ||||
|  | ||||
| static | ||||
| int GetLine(int sockfd, char *buf, struct UrlData *data) | ||||
| int GetLine(int sockfd, char *buf, struct connectdata *conn) | ||||
| { | ||||
|   int nread; | ||||
|   ssize_t nread; | ||||
|   int read_rc=1; | ||||
|   char *ptr; | ||||
|   struct UrlData *data=conn->data; | ||||
|  | ||||
|   ptr=buf; | ||||
|  | ||||
|   /* get us a full line, terminated with a newline */ | ||||
|   for(nread=0; | ||||
|       (nread<BUFSIZE) && read_rc; | ||||
|       nread++, ptr++) { | ||||
| #ifdef USE_SSLEAY | ||||
|     if (data->ssl.use) { | ||||
|       read_rc = SSL_read(data->ssl.handle, ptr, 1); | ||||
|     } | ||||
|     else { | ||||
| #endif | ||||
|       read_rc = sread(sockfd, ptr, 1); | ||||
| #ifdef USE_SSLEAY | ||||
|     } | ||||
| #endif /* USE_SSLEAY */ | ||||
|     if (*ptr == '\n') | ||||
|     if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) || | ||||
|        (nread <= 0) || | ||||
|        (*ptr == '\n')) | ||||
|       break; | ||||
|   } | ||||
|   *ptr=0; /* zero terminate */ | ||||
| @@ -244,7 +237,7 @@ int GetLine(int sockfd, char *buf, struct UrlData *data) | ||||
|     fwrite(buf, 1, nread, data->err); | ||||
|     fputs("\n", data->err); | ||||
|   } | ||||
|   return nread; | ||||
|   return nread>0?nread:0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -272,27 +265,29 @@ bool static checkheaders(struct UrlData *data, char *thisheader) | ||||
|  * this proxy. After that, the socket can be used just as a normal socket. | ||||
|  */ | ||||
|  | ||||
| CURLcode Curl_ConnectHTTPProxyTunnel(struct UrlData *data, int tunnelsocket, | ||||
| CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | ||||
|                                      int tunnelsocket, | ||||
|                                      char *hostname, int remote_port) | ||||
| { | ||||
|   int httperror=0; | ||||
|   int subversion=0; | ||||
|   struct UrlData *data=conn->data; | ||||
|  | ||||
|   infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); | ||||
|  | ||||
|   /* OK, now send the connect statment */ | ||||
|   sendf(tunnelsocket, data, | ||||
|   /* OK, now send the connect request to the proxy */ | ||||
|   Curl_sendf(tunnelsocket, conn, | ||||
|              "CONNECT %s:%d HTTP/1.0\015\012" | ||||
|              "%s" | ||||
|              "%s" | ||||
|              "\r\n", | ||||
|              hostname, remote_port, | ||||
|         (data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"", | ||||
|         (data->useragent?data->ptr_uagent:"") | ||||
|              (data->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"", | ||||
|              (data->useragent?conn->allocptr.uagent:"") | ||||
|              ); | ||||
|  | ||||
|   /* wait for the proxy to send us a HTTP/1.0 200 OK header */ | ||||
|   while(GetLine(tunnelsocket, data->buffer, data)) { | ||||
|   while(GetLine(tunnelsocket, data->buffer, conn)) { | ||||
|     if('\r' == data->buffer[0]) | ||||
|       break; /* end of headers */ | ||||
|     if(2 == sscanf(data->buffer, "HTTP/1.%d %d", | ||||
| @@ -330,21 +325,21 @@ CURLcode Curl_http_connect(struct connectdata *conn) | ||||
|   if (conn->protocol & PROT_HTTPS) { | ||||
|     if (data->bits.httpproxy) { | ||||
|       /* HTTPS through a proxy can only be done with a tunnel */ | ||||
|       result = Curl_ConnectHTTPProxyTunnel(data, data->firstsocket, | ||||
|                                            data->hostname, data->remote_port); | ||||
|       result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket, | ||||
|                                            conn->hostname, conn->remote_port); | ||||
|       if(CURLE_OK != result) | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     /* now, perform the SSL initialization for this socket */ | ||||
|     if(Curl_SSLConnect(data)) | ||||
|     if(Curl_SSLConnect(conn)) | ||||
|       return CURLE_SSL_CONNECT_ERROR; | ||||
|   } | ||||
|  | ||||
|   if(data->bits.user_passwd && !data->bits.this_is_a_follow) { | ||||
|     /* Authorization: is requested, this is not a followed location, get the | ||||
|        original host name */ | ||||
|     data->auth_host = strdup(data->hostname); | ||||
|     data->auth_host = strdup(conn->hostname); | ||||
|   } | ||||
|  | ||||
|   return CURLE_OK; | ||||
| @@ -366,7 +361,7 @@ CURLcode Curl_http_done(struct connectdata *conn) | ||||
|   struct HTTP *http; | ||||
|  | ||||
|   data=conn->data; | ||||
|   http=data->proto.http; | ||||
|   http=conn->proto.http; | ||||
|  | ||||
|   if(data->bits.http_formpost) { | ||||
|     *bytecount = http->readbytecount + http->writebytecount; | ||||
| @@ -380,9 +375,6 @@ CURLcode Curl_http_done(struct connectdata *conn) | ||||
|     *bytecount = http->readbytecount + http->writebytecount; | ||||
|   } | ||||
|  | ||||
|   free(http); | ||||
|   data->proto.http=NULL; /* it is gone */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| @@ -398,11 +390,17 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|   char *host = conn->name; | ||||
|   long *bytecount = &conn->bytecount; | ||||
|  | ||||
|   if(!conn->proto.http) { | ||||
|     /* Only allocate this struct if we don't already have it! */ | ||||
|  | ||||
|     http = (struct HTTP *)malloc(sizeof(struct HTTP)); | ||||
|     if(!http) | ||||
|       return CURLE_OUT_OF_MEMORY; | ||||
|     memset(http, 0, sizeof(struct HTTP)); | ||||
|   data->proto.http = http; | ||||
|     conn->proto.http = http; | ||||
|   } | ||||
|   else | ||||
|     http = conn->proto.http; | ||||
|  | ||||
|   if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) && | ||||
|        data->bits.upload) { | ||||
| @@ -413,9 +411,9 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|      have been used in the proxy connect, but if we have got a header with | ||||
|      the user-agent string specified, we erase the previously made string | ||||
|      here. */ | ||||
|   if(checkheaders(data, "User-Agent:") && data->ptr_uagent) { | ||||
|     free(data->ptr_uagent); | ||||
|     data->ptr_uagent=NULL; | ||||
|   if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) { | ||||
|     free(conn->allocptr.uagent); | ||||
|     conn->allocptr.uagent=NULL; | ||||
|   } | ||||
|  | ||||
|   if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) { | ||||
| @@ -425,24 +423,27 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|        host due to a location-follow, we do some weirdo checks here */ | ||||
|     if(!data->bits.this_is_a_follow || | ||||
|        !data->auth_host || | ||||
|        strequal(data->auth_host, data->hostname)) { | ||||
|        strequal(data->auth_host, conn->hostname)) { | ||||
|       sprintf(data->buffer, "%s:%s", data->user, data->passwd); | ||||
|       if(Curl_base64_encode(data->buffer, strlen(data->buffer), | ||||
|                             &authorization) >= 0) { | ||||
|         data->ptr_userpwd = aprintf( "Authorization: Basic %s\015\012", | ||||
|         if(conn->allocptr.userpwd) | ||||
|           free(conn->allocptr.userpwd); | ||||
|         conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012", | ||||
|                                      authorization); | ||||
|         free(authorization); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if((data->bits.set_range) && !checkheaders(data, "Range:")) { | ||||
|     data->ptr_rangeline = aprintf("Range: bytes=%s\015\012", data->range); | ||||
|   } | ||||
|   if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) { | ||||
|     data->ptr_ref = aprintf("Referer: %s\015\012", data->referer); | ||||
|     if(conn->allocptr.ref) | ||||
|       free(conn->allocptr.ref); | ||||
|     conn->allocptr.ref = aprintf("Referer: %s\015\012", data->referer); | ||||
|   } | ||||
|   if(data->cookie && !checkheaders(data, "Cookie:")) { | ||||
|     data->ptr_cookie = aprintf("Cookie: %s\015\012", data->cookie); | ||||
|     if(conn->allocptr.cookie) | ||||
|       free(conn->allocptr.cookie); | ||||
|     conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->cookie); | ||||
|   } | ||||
|  | ||||
|   if(data->cookies) { | ||||
| @@ -461,14 +462,19 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|     http->sendit = Curl_getFormData(data->httppost, &http->postsize); | ||||
|   } | ||||
|  | ||||
|   if(!checkheaders(data, "Host:")) { | ||||
|     if(((conn->protocol&PROT_HTTPS) && (data->remote_port == PORT_HTTPS)) || | ||||
|        (!(conn->protocol&PROT_HTTPS) && (data->remote_port == PORT_HTTP)) ) | ||||
|   if(!checkheaders(data, "Host:") && | ||||
|      !conn->allocptr.host) { | ||||
|     /* if ptr_host is already set, it is OK since we only re-use connections | ||||
|        to the very same host and port */ | ||||
|  | ||||
|     if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) || | ||||
|        (!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) ) | ||||
|       /* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include | ||||
|          the port number in the host string */ | ||||
|       data->ptr_host = aprintf("Host: %s\r\n", host); | ||||
|       conn->allocptr.host = aprintf("Host: %s\r\n", host); | ||||
|     else | ||||
|       data->ptr_host = aprintf("Host: %s:%d\r\n", host, data->remote_port); | ||||
|       conn->allocptr.host = aprintf("Host: %s:%d\r\n", host, | ||||
|                                     conn->remote_port); | ||||
|   } | ||||
|  | ||||
|   if(!checkheaders(data, "Pragma:")) | ||||
| @@ -477,6 +483,92 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|   if(!checkheaders(data, "Accept:")) | ||||
|     http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"; | ||||
|  | ||||
|   if((data->bits.http_post || | ||||
|       data->bits.http_formpost || | ||||
|       data->bits.http_put) && | ||||
|      data->resume_from) { | ||||
|     /********************************************************************** | ||||
|      * Resuming upload in HTTP means that we PUT or POST and that we have | ||||
|      * got a resume_from value set. The resume value has already created | ||||
|      * a Range: header that will be passed along. We need to "fast forward" | ||||
|      * the file the given number of bytes and decrease the assume upload | ||||
|      * file size before we continue this venture in the dark lands of HTTP. | ||||
|      *********************************************************************/ | ||||
|     | ||||
|     if(data->resume_from < 0 ) { | ||||
|       /* | ||||
|        * This is meant to get the size of the present remote-file by itself. | ||||
|        * We don't support this now. Bail out! | ||||
|        */ | ||||
|        data->resume_from = 0; | ||||
|     } | ||||
|  | ||||
|     if(data->resume_from) { | ||||
|       /* do we still game? */ | ||||
|       int passed=0; | ||||
|  | ||||
|       /* Now, let's read off the proper amount of bytes from the | ||||
|          input. If we knew it was a proper file we could've just | ||||
|          fseek()ed but we only have a stream here */ | ||||
|       do { | ||||
|         int readthisamountnow = (data->resume_from - passed); | ||||
|         int actuallyread; | ||||
|  | ||||
|         if(readthisamountnow > BUFSIZE) | ||||
|           readthisamountnow = BUFSIZE; | ||||
|  | ||||
|         actuallyread = | ||||
|           data->fread(data->buffer, 1, readthisamountnow, data->in); | ||||
|  | ||||
|         passed += actuallyread; | ||||
|         if(actuallyread != readthisamountnow) { | ||||
|           failf(data, "Could only read %d bytes from the input\n", | ||||
|                 passed); | ||||
|           return CURLE_READ_ERROR; | ||||
|         } | ||||
|       } while(passed != data->resume_from); /* loop until done */ | ||||
|  | ||||
|       /* now, decrease the size of the read */ | ||||
|       if(data->infilesize>0) { | ||||
|         data->infilesize -= data->resume_from; | ||||
|  | ||||
|         if(data->infilesize <= 0) { | ||||
|           failf(data, "File already completely uploaded\n"); | ||||
|           return CURLE_PARTIAL_FILE; | ||||
|         } | ||||
|       } | ||||
|       /* we've passed, proceed as normal */ | ||||
|     } | ||||
|   } | ||||
|   if(data->bits.set_range) { | ||||
|     /* | ||||
|      * A range is selected. We use different headers whether we're downloading | ||||
|      * or uploading and we always let customized headers override our internal | ||||
|      * ones if any such are specified. | ||||
|      */ | ||||
|     if((data->httpreq == HTTPREQ_GET) && | ||||
|        !checkheaders(data, "Range:")) { | ||||
|       conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->range); | ||||
|     } | ||||
|     else if((data->httpreq != HTTPREQ_GET) && | ||||
|             !checkheaders(data, "Content-Range:")) { | ||||
|  | ||||
|       if(data->resume_from) { | ||||
|         /* This is because "resume" was selected */ | ||||
|         long total_expected_size= data->resume_from + data->infilesize; | ||||
|         conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n", | ||||
|                                       data->range, total_expected_size-1, | ||||
|                                       total_expected_size); | ||||
|       } | ||||
|       else { | ||||
|         /* Range was selected and then we just pass the incoming range and  | ||||
|            append total size */ | ||||
|         conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n", | ||||
|                                       data->range, data->infilesize); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   do { | ||||
|     send_buffer *req_buffer; | ||||
|     struct curl_slist *headers=data->headers; | ||||
| @@ -487,7 +579,7 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|     /* add the main request stuff */ | ||||
|     add_bufferf(req_buffer, | ||||
|                 "%s " /* GET/HEAD/POST/PUT */ | ||||
|                 "%s HTTP/1.0\r\n" /* path */ | ||||
|                 "%s HTTP/1.1\r\n" /* path */ | ||||
|                 "%s" /* proxyuserpwd */ | ||||
|                 "%s" /* userpwd */ | ||||
|                 "%s" /* range */ | ||||
| @@ -503,15 +595,15 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|                  (data->bits.http_post || data->bits.http_formpost)?"POST": | ||||
|                  (data->bits.http_put)?"PUT":"GET"), | ||||
|                 ppath, | ||||
|                 (data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"", | ||||
|                 (data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"", | ||||
|                 (data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"", | ||||
|                 (data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"", | ||||
|                 (data->ptr_cookie?data->ptr_cookie:""), /* Cookie: <data> */ | ||||
|                 (data->ptr_host?data->ptr_host:""), /* Host: host */ | ||||
|                 (data->bits.proxy_user_passwd && conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"", | ||||
|                 (data->bits.user_passwd && conn->allocptr.userpwd)?conn->allocptr.userpwd:"", | ||||
|                 (data->bits.set_range && conn->allocptr.rangeline)?conn->allocptr.rangeline:"", | ||||
|                 (data->useragent && *data->useragent && conn->allocptr.uagent)?conn->allocptr.uagent:"", | ||||
|                 (conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: <data> */ | ||||
|                 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ | ||||
|                 http->p_pragma?http->p_pragma:"", | ||||
|                 http->p_accept?http->p_accept:"", | ||||
|                 (data->bits.http_set_referer && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */ | ||||
|                 (data->bits.http_set_referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */ | ||||
|                 ); | ||||
|  | ||||
|     if(co) { | ||||
| @@ -615,10 +707,10 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|       Curl_pgrsSetUploadSize(data, http->postsize); | ||||
|  | ||||
|       data->request_size =  | ||||
|         add_buffer_send(data->firstsocket, conn, req_buffer); | ||||
|       result = Curl_Transfer(conn, data->firstsocket, -1, TRUE, | ||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); | ||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, | ||||
|                         &http->readbytecount, | ||||
|                           data->firstsocket, | ||||
|                           conn->firstsocket, | ||||
|                         &http->writebytecount); | ||||
|       if(result) { | ||||
|         Curl_FormFree(http->sendit); /* free that whole lot */ | ||||
| @@ -641,12 +733,12 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|  | ||||
|       /* this sends the buffer and frees all the buffer resources */ | ||||
|       data->request_size =  | ||||
|         add_buffer_send(data->firstsocket, conn, req_buffer); | ||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); | ||||
|  | ||||
|       /* prepare for transfer */ | ||||
|       result = Curl_Transfer(conn, data->firstsocket, -1, TRUE, | ||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, | ||||
|                         &http->readbytecount, | ||||
|                         data->firstsocket, | ||||
|                         conn->firstsocket, | ||||
|                         &http->writebytecount); | ||||
|       if(result) | ||||
|         return result; | ||||
| @@ -687,10 +779,10 @@ CURLcode Curl_http(struct connectdata *conn) | ||||
|  | ||||
|       /* issue the request */ | ||||
|       data->request_size =  | ||||
|         add_buffer_send(data->firstsocket, conn, req_buffer); | ||||
|         add_buffer_send(conn->firstsocket, conn, req_buffer); | ||||
|  | ||||
|       /* HTTP GET/HEAD download: */ | ||||
|       result = Curl_Transfer(conn, data->firstsocket, -1, TRUE, bytecount, | ||||
|       result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, bytecount, | ||||
|                         -1, NULL); /* nothing to upload */ | ||||
|     } | ||||
|     if(result) | ||||
|   | ||||
| @@ -25,7 +25,8 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /* ftp can use this as well */ | ||||
| CURLcode Curl_ConnectHTTPProxyTunnel(struct UrlData *data, int tunnelsocket, | ||||
| CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | ||||
|                                      int tunnelsocket, | ||||
|                                      char *hostname, int remote_port); | ||||
|  | ||||
| /* protocol-specific functions set up to be called by the main engine */ | ||||
|   | ||||
| @@ -32,7 +32,7 @@ | ||||
| #include <unistd.h> | ||||
| #endif | ||||
|  | ||||
| #if ! defined(WIN32) && ! defined(__BEOS__) | ||||
| #if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__) | ||||
|  | ||||
| #ifdef NEED_REENTRANT | ||||
| #define _REENTRANT | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
|  *****************************************************************************/ | ||||
| #include "setup.h" | ||||
|  | ||||
| #if ! defined(WIN32) && ! defined(__BEOS__) | ||||
| #if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__) | ||||
| extern char *Curl_if2ip(char *interface, char *buf, int buf_size); | ||||
| #else | ||||
| #define Curl_if2ip(a,b,c) NULL | ||||
|   | ||||
							
								
								
									
										22
									
								
								lib/krb4.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								lib/krb4.c
									
									
									
									
									
								
							| @@ -283,12 +283,14 @@ krb4_auth(void *app_data, struct connectdata *conn) | ||||
|     u_int32_t cs; | ||||
|     struct krb4_data *d = app_data; | ||||
|     struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR; | ||||
| #if 0 | ||||
|     struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR; | ||||
| #endif | ||||
|     char *host = conn->hp->h_name; | ||||
|     size_t nread; | ||||
|     int l = sizeof(local_addr); | ||||
|  | ||||
|     if(getsockname(conn->data->firstsocket, | ||||
|     if(getsockname(conn->firstsocket, | ||||
|                    (struct sockaddr *)LOCAL_ADDR, &l) < 0) | ||||
| 	perror("getsockname()"); | ||||
|  | ||||
| @@ -313,7 +315,7 @@ krb4_auth(void *app_data, struct connectdata *conn) | ||||
|       else { | ||||
| 	if (natAddr.s_addr != localaddr->sin_addr.s_addr) { | ||||
| 	  printf("Using NAT IP address (%s) for kerberos 4\n", | ||||
| 		 inet_ntoa(natAddr)); | ||||
| 		 (char *)inet_ntoa(natAddr)); | ||||
| 	  localaddr->sin_addr = natAddr; | ||||
| 	   | ||||
| 	  /* | ||||
| @@ -337,9 +339,9 @@ krb4_auth(void *app_data, struct connectdata *conn) | ||||
| 	return AUTH_CONTINUE; | ||||
|     } | ||||
|     /*ret = command("ADAT %s", p)*/ | ||||
|     Curl_ftpsendf(conn->data->firstsocket, conn, "ADAT %s", p); | ||||
|     Curl_ftpsendf(conn->firstsocket, conn, "ADAT %s", p); | ||||
|     /* wait for feedback */ | ||||
|     nread = Curl_GetFTPResponse(conn->data->firstsocket, | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                                 conn->data->buffer, conn, NULL); | ||||
|     if(nread < 0) | ||||
| 	return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
| @@ -399,7 +401,6 @@ void krb_kauth(struct connectdata *conn) | ||||
|     KTEXT_ST tkt, tktcopy; | ||||
|     char *name; | ||||
|     char *p; | ||||
|     int overbose; | ||||
|     char passwd[100]; | ||||
|     int tmp; | ||||
|     size_t nread; | ||||
| @@ -408,21 +409,19 @@ void krb_kauth(struct connectdata *conn) | ||||
|  | ||||
|     save = set_command_prot(conn, prot_private); | ||||
|     /*ret = command("SITE KAUTH %s", name);***/ | ||||
|     Curl_ftpsendf(conn->data->firstsocket, conn, | ||||
|     Curl_ftpsendf(conn->firstsocket, conn, | ||||
|              "SITE KAUTH %s", conn->data->user); | ||||
|     /* wait for feedback */ | ||||
|     nread = Curl_GetFTPResponse(conn->data->firstsocket, conn->data->buffer, | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->buffer, | ||||
|                                 conn, NULL); | ||||
|     if(nread < 0) | ||||
| 	return /*CURLE_OPERATION_TIMEOUTED*/; | ||||
|  | ||||
|     if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){ | ||||
| 	/*verbose = overbose;***/ | ||||
| 	set_command_prot(conn, save); | ||||
| 	/*code = -1;***/ | ||||
| 	return; | ||||
|     } | ||||
|     /*verbose = overbose;***/ | ||||
|     p = strstr(/*reply_string***/conn->data->buffer, "T="); | ||||
|     if(!p){ | ||||
| 	printf("Bad reply from server.\n"); | ||||
| @@ -444,7 +443,6 @@ void krb_kauth(struct connectdata *conn) | ||||
|     p = strstr(/*reply_string***/conn->data->buffer, "P="); | ||||
|     if(!p){ | ||||
| 	printf("Bad reply from server.\n"); | ||||
| 	/*verbose = overbose;***/ | ||||
| 	set_command_prot(conn, save); | ||||
| 	/*code = -1;***/ | ||||
| 	return; | ||||
| @@ -488,10 +486,10 @@ void krb_kauth(struct connectdata *conn) | ||||
|     } | ||||
|     memset (tktcopy.dat, 0, tktcopy.length); | ||||
|     /*ret = command("SITE KAUTH %s %s", name, p);***/ | ||||
|     Curl_ftpsendf(conn->data->firstsocket, conn, | ||||
|     Curl_ftpsendf(conn->firstsocket, conn, | ||||
|              "SITE KAUTH %s %s", name, p); | ||||
|     /* wait for feedback */ | ||||
|     nread = Curl_GetFTPResponse(conn->data->firstsocket, conn->data->buffer, | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->buffer, | ||||
|                                 conn, NULL); | ||||
|     if(nread < 0) | ||||
| 	return /*CURLE_OPERATION_TIMEOUTED*/; | ||||
|   | ||||
| @@ -171,10 +171,10 @@ CURLcode Curl_ldap(struct connectdata *conn) | ||||
|   DYNA_GET_FUNCTION(int (*)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long), ldap_entry2text); | ||||
|   DYNA_GET_FUNCTION(int (*)(void *, char *, void *, void *, char **, char **, int (*)(void *, char *, int), void *, char *, int, unsigned long, char *, char *), ldap_entry2html); | ||||
|    | ||||
|   server = ldap_open(data->hostname, data->port); | ||||
|   server = ldap_open(conn->hostname, conn->port); | ||||
|   if (server == NULL) { | ||||
|     failf(data, "LDAP: Cannot connect to %s:%d", | ||||
| 	  data->hostname, data->port); | ||||
| 	  conn->hostname, conn->port); | ||||
|     status = CURLE_COULDNT_CONNECT; | ||||
|   } else { | ||||
|     rc = ldap_simple_bind_s(server, data->user, data->passwd); | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| ; Definition file for the DLL version of the LIBCURL library from curl | ||||
| ; | ||||
|  | ||||
| LIBRARY		LIBCURL | ||||
| LIBRARY		CURL | ||||
|  | ||||
| DESCRIPTION	'curl libcurl - http://curl.haxx.se' | ||||
|  | ||||
| @@ -32,11 +32,11 @@ EXPORTS | ||||
| 	curl_unescape @ 23 ;  | ||||
| 	curl_version @ 24 ;  | ||||
| 	curl_write @ 25 ;  | ||||
| 	maprintf @ 26 ;  | ||||
|  	mfprintf @ 27 ; | ||||
|  	mprintf @ 28 ; | ||||
|  	msprintf @ 29 ; | ||||
|  	msnprintf @ 30 ; | ||||
|  	mvfprintf @ 31 ; | ||||
| 	strequal @ 32 ;  | ||||
| 	strnequal @ 33 ;  | ||||
| 	curl_maprintf @ 26 ;  | ||||
|  	curl_mfprintf @ 27 ; | ||||
|  	curl_mprintf @ 28 ; | ||||
|  	curl_msprintf @ 29 ; | ||||
|  	curl_msnprintf @ 30 ; | ||||
|  	curl_mvfprintf @ 31 ; | ||||
| 	Curl_strequal @ 32 ;  | ||||
| 	Curl_strnequal @ 33 ;  | ||||
|   | ||||
| @@ -72,7 +72,7 @@ void *curl_domalloc(size_t size, int line, char *source) | ||||
|   return mem; | ||||
| } | ||||
|  | ||||
| char *curl_dostrdup(char *str, int line, char *source) | ||||
| char *curl_dostrdup(const char *str, int line, char *source) | ||||
| { | ||||
|   char *mem; | ||||
|   size_t len; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| void *curl_domalloc(size_t size, int line, char *source); | ||||
| void *curl_dorealloc(void *ptr, size_t size, int line, char *source); | ||||
| void curl_dofree(void *ptr, int line, char *source); | ||||
| char *curl_dostrdup(char *str, int line, char *source); | ||||
| char *curl_dostrdup(const char *str, int line, char *source); | ||||
| void curl_memdebug(char *logname); | ||||
|  | ||||
| /* file descriptor manipulators */ | ||||
|   | ||||
| @@ -27,7 +27,8 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "getenv.h" | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| #include "strequal.h" | ||||
|  | ||||
| /* Debug this single source file with: | ||||
|   | ||||
| @@ -203,6 +203,9 @@ int Curl_pgrsUpdate(struct UrlData *data) | ||||
|          even when not displayed! */ | ||||
|   else if(!(data->progress.flags & PGRS_HEADERS_OUT)) { | ||||
|     if (!data->progress.callback) { | ||||
|       if(data->resume_from) | ||||
|         fprintf(data->err, "** Resuming transfer from byte position %d\n", | ||||
|                 data->resume_from); | ||||
|       fprintf(data->err, | ||||
|               "  %% Total    %% Received %% Xferd  Average Speed          Time             Curr.\n" | ||||
|               "                                 Dload  Upload Total    Current  Left    Speed\n"); | ||||
| @@ -212,14 +215,14 @@ int Curl_pgrsUpdate(struct UrlData *data) | ||||
|  | ||||
|   now = Curl_tvnow(); /* what time is it */ | ||||
|  | ||||
|   /* The exact time spent so far */ | ||||
|   data->progress.timespent = Curl_tvdiff (now, data->progress.start); | ||||
|  | ||||
|   if(data->progress.lastshow == Curl_tvlong(now)) | ||||
|     return 0; /* never update this more than once a second if the end isn't  | ||||
|                  reached */ | ||||
|   data->progress.lastshow = now.tv_sec; | ||||
|  | ||||
|   /* The exact time spent so far */ | ||||
|   data->progress.timespent = Curl_tvdiff (now, data->progress.start); | ||||
|  | ||||
|   /* The average download speed this far */ | ||||
|   data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0); | ||||
|  | ||||
| @@ -257,17 +260,13 @@ int Curl_pgrsUpdate(struct UrlData *data) | ||||
|   } | ||||
|  | ||||
|       /* Figure out the estimated time of arrival for the upload */ | ||||
|   if(data->progress.flags & PGRS_UL_SIZE_KNOWN) { | ||||
|     if(!data->progress.ulspeed) | ||||
|       data->progress.ulspeed=1; | ||||
|   if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && data->progress.ulspeed){ | ||||
|     ulestimate = data->progress.size_ul / data->progress.ulspeed; | ||||
|     ulpercen = (data->progress.uploaded / data->progress.size_ul)*100; | ||||
|   } | ||||
|  | ||||
|   /* ... and the download */ | ||||
|   if(data->progress.flags & PGRS_DL_SIZE_KNOWN) { | ||||
|     if(!data->progress.dlspeed) | ||||
|       data->progress.dlspeed=1; | ||||
|   if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && data->progress.dlspeed) { | ||||
|     dlestimate = data->progress.size_dl / data->progress.dlspeed; | ||||
|     dlpercen = (data->progress.downloaded / data->progress.size_dl)*100; | ||||
|   } | ||||
|   | ||||
| @@ -482,10 +482,10 @@ sec_prot_internal(struct connectdata *conn, int level) | ||||
|     } | ||||
|  | ||||
|     if(level){ | ||||
|       Curl_ftpsendf(conn->data->firstsocket, conn, | ||||
|       Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                     "PBSZ %u", s); | ||||
|       /* wait for feedback */ | ||||
|       nread = Curl_GetFTPResponse(conn->data->firstsocket, | ||||
|       nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                                   conn->data->buffer, conn, NULL); | ||||
|       if(nread < 0) | ||||
|         return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
| @@ -501,10 +501,10 @@ sec_prot_internal(struct connectdata *conn, int level) | ||||
|         conn->buffer_size = s; | ||||
|     } | ||||
|  | ||||
|     Curl_ftpsendf(conn->data->firstsocket, conn, | ||||
|     Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                   "PROT %c", level["CSEP"]); | ||||
|     /* wait for feedback */ | ||||
|     nread = Curl_GetFTPResponse(conn->data->firstsocket, | ||||
|     nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                                 conn->data->buffer, conn, NULL); | ||||
|     if(nread < 0) | ||||
|       return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
| @@ -610,10 +610,10 @@ sec_login(struct connectdata *conn) | ||||
| 	} | ||||
| 	infof(data, "Trying %s...\n", (*m)->name); | ||||
| 	/*ret = command("AUTH %s", (*m)->name);***/ | ||||
| 	Curl_ftpsendf(conn->data->firstsocket, conn, | ||||
| 	Curl_ftpsendf(conn->firstsocket, conn, | ||||
|                  "AUTH %s", (*m)->name); | ||||
| 	/* wait for feedback */ | ||||
| 	nread = Curl_GetFTPResponse(conn->data->firstsocket, | ||||
| 	nread = Curl_GetFTPResponse(conn->firstsocket, | ||||
|                                     conn->data->buffer, conn, NULL); | ||||
| 	if(nread < 0) | ||||
| 	    return /*CURLE_OPERATION_TIMEOUTED*/-1; | ||||
|   | ||||
							
								
								
									
										196
									
								
								lib/sendf.c
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								lib/sendf.c
									
									
									
									
									
								
							| @@ -50,6 +50,76 @@ | ||||
| #include "memdebug.h" | ||||
| #endif | ||||
|  | ||||
| /* returns last node in linked list */ | ||||
| static struct curl_slist *slist_get_last(struct curl_slist *list) | ||||
| { | ||||
| 	struct curl_slist	*item; | ||||
|  | ||||
| 	/* if caller passed us a NULL, return now */ | ||||
| 	if (!list) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* loop through to find the last item */ | ||||
| 	item = list; | ||||
| 	while (item->next) { | ||||
| 		item = item->next; | ||||
| 	} | ||||
| 	return item; | ||||
| } | ||||
|  | ||||
| /* append a struct to the linked list. It always retunrs the address of the | ||||
|  * first record, so that you can sure this function as an initialization | ||||
|  * function as well as an append function. If you find this bothersome, | ||||
|  * then simply create a separate _init function and call it appropriately from | ||||
|  * within the proram. */ | ||||
| struct curl_slist *curl_slist_append(struct curl_slist *list, | ||||
|                                      const char *data) | ||||
| { | ||||
| 	struct curl_slist	*last; | ||||
| 	struct curl_slist	*new_item; | ||||
|  | ||||
| 	new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist)); | ||||
| 	if (new_item) { | ||||
| 		new_item->next = NULL; | ||||
| 		new_item->data = strdup(data); | ||||
| 	} | ||||
| 	else { | ||||
| 		fprintf(stderr, "Cannot allocate memory for QUOTE list.\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (list) { | ||||
| 		last = slist_get_last(list); | ||||
| 		last->next = new_item; | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	/* if this is the first item, then new_item *is* the list */ | ||||
| 	return new_item; | ||||
| } | ||||
|  | ||||
| /* be nice and clean up resources */ | ||||
| void curl_slist_free_all(struct curl_slist *list) | ||||
| { | ||||
| 	struct curl_slist	*next; | ||||
| 	struct curl_slist	*item; | ||||
|  | ||||
| 	if (!list) | ||||
| 		return; | ||||
|  | ||||
| 	item = list; | ||||
| 	do { | ||||
| 		next = item->next; | ||||
| 		 | ||||
| 		if (item->data) { | ||||
| 			free(item->data); | ||||
| 		} | ||||
| 		free(item); | ||||
| 		item = next; | ||||
| 	} while (next); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* infof() is for info message along the way */ | ||||
|  | ||||
| void Curl_infof(struct UrlData *data, char *fmt, ...) | ||||
| @@ -72,64 +142,94 @@ void Curl_failf(struct UrlData *data, char *fmt, ...) | ||||
|   va_start(ap, fmt); | ||||
|   if(data->errorbuffer) | ||||
|     vsnprintf(data->errorbuffer, CURL_ERROR_SIZE, fmt, ap); | ||||
|   else /* no errorbuffer receives this, write to data->err instead */ | ||||
|   else { | ||||
|     /* no errorbuffer receives this, write to data->err instead */ | ||||
|     vfprintf(data->err, fmt, ap); | ||||
|     fprintf(data->err, "\n"); | ||||
|   } | ||||
|   va_end(ap); | ||||
| } | ||||
|  | ||||
| /* sendf() sends the formated data to the server */ | ||||
| size_t Curl_sendf(int fd, struct UrlData *data, char *fmt, ...) | ||||
| /* Curl_sendf() sends formated data to the server */ | ||||
| size_t Curl_sendf(int sockfd, struct connectdata *conn, | ||||
|                   char *fmt, ...) | ||||
| { | ||||
|   struct UrlData *data = conn->data; | ||||
|   size_t bytes_written; | ||||
|   char *s; | ||||
|   va_list ap; | ||||
|   va_start(ap, fmt); | ||||
|   s = vaprintf(fmt, ap); | ||||
|   s = vaprintf(fmt, ap); /* returns an allocated string */ | ||||
|   va_end(ap); | ||||
|   if(!s) | ||||
|     return 0; /* failure */ | ||||
|   if(data->bits.verbose) | ||||
|     fprintf(data->err, "> %s", s); | ||||
|  | ||||
| #ifndef USE_SSLEAY | ||||
|   bytes_written = swrite(fd, s, strlen(s)); | ||||
| #else /* USE_SSLEAY */ | ||||
|   if (data->ssl.use) { | ||||
|     bytes_written = SSL_write(data->ssl.handle, s, strlen(s)); | ||||
|   } else { | ||||
|     bytes_written = swrite(fd, s, strlen(s)); | ||||
|   } | ||||
| #endif /* USE_SSLEAY */ | ||||
|   /* Write the buffer to the socket */ | ||||
|   Curl_write(conn, sockfd, s, strlen(s), &bytes_written); | ||||
|  | ||||
|   free(s); /* free the output string */ | ||||
|   return(bytes_written); | ||||
|  | ||||
|   return bytes_written; | ||||
| } | ||||
|  | ||||
| /* ssend() sends plain (binary) data to the server */ | ||||
| size_t Curl_ssend(int fd, struct connectdata *conn, void *mem, size_t len) | ||||
| /* | ||||
|  * Curl_write() is an internal write function that sends plain (binary) data | ||||
|  * to the server. Works with plain sockets, SSL or kerberos. | ||||
|  * | ||||
|  */ | ||||
| CURLcode Curl_write(struct connectdata *conn, int sockfd, | ||||
|                     void *mem, size_t len, | ||||
|                     size_t *written) | ||||
| { | ||||
|   size_t bytes_written; | ||||
|   struct UrlData *data=conn->data; /* conn knows data, not vice versa */ | ||||
|  | ||||
| #ifdef USE_SSLEAY | ||||
|   if (data->ssl.use) { | ||||
|     bytes_written = SSL_write(data->ssl.handle, mem, len); | ||||
|   if (conn->ssl.use) { | ||||
|     int loop=100; /* just a precaution to never loop endlessly */ | ||||
|     while(loop--) { | ||||
|       bytes_written = SSL_write(conn->ssl.handle, mem, len); | ||||
|       if((-1 != bytes_written) || | ||||
|          (SSL_ERROR_WANT_WRITE != SSL_get_error(conn->ssl.handle, | ||||
|                                                 bytes_written) )) | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
| #endif | ||||
| #ifdef KRB4 | ||||
|     if(conn->sec_complete) { | ||||
|       bytes_written = sec_write(conn, fd, mem, len); | ||||
|       bytes_written = sec_write(conn, sockfd, mem, len); | ||||
|     } | ||||
|     else | ||||
| #endif /* KRB4 */ | ||||
|       bytes_written = swrite(fd, mem, len); | ||||
|       bytes_written = swrite(sockfd, mem, len); | ||||
| #ifdef USE_SSLEAY | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   return bytes_written; | ||||
|   *written = bytes_written; | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * External write-function, writes to the data-socket. | ||||
|  * Takes care of plain sockets, SSL or kerberos transparently. | ||||
|  */ | ||||
| CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, | ||||
|                    size_t *n) | ||||
| { | ||||
|   struct connectdata *conn = (struct connectdata *)c_conn; | ||||
|  | ||||
|   if(!n || !conn || (conn->handle != STRUCT_CONNECT)) | ||||
|     return CURLE_FAILED_INIT; | ||||
|  | ||||
|   return Curl_write(conn, conn->sockfd, buf, amount, n); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* client_write() sends data to the write callback(s) | ||||
|  | ||||
|    The bit pattern defines to what "streams" to write to. Body and/or header. | ||||
| @@ -163,3 +263,55 @@ CURLcode Curl_client_write(struct UrlData *data, | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Internal read-from-socket function. This is meant to deal with plain | ||||
|  * sockets, SSL sockets and kerberos sockets. | ||||
|  */ | ||||
| CURLcode Curl_read(struct connectdata *conn, int sockfd, | ||||
|                    char *buf, size_t buffersize, | ||||
|                    ssize_t *n) | ||||
| { | ||||
|   ssize_t nread; | ||||
|  | ||||
| #ifdef USE_SSLEAY | ||||
|   if (conn->ssl.use) { | ||||
|     int loop=100; /* just a precaution to never loop endlessly */ | ||||
|     while(loop--) { | ||||
|       nread = SSL_read(conn->ssl.handle, buf, buffersize); | ||||
|       if((-1 != nread) || | ||||
|          (SSL_ERROR_WANT_READ != SSL_get_error(conn->ssl.handle, nread) )) | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
| #endif | ||||
| #ifdef KRB4 | ||||
|     if(conn->sec_complete) | ||||
|       nread = sec_read(conn, sockfd, buf, buffersize); | ||||
|     else | ||||
| #endif | ||||
|       nread = sread (sockfd, buf, buffersize); | ||||
| #ifdef USE_SSLEAY | ||||
|   } | ||||
| #endif /* USE_SSLEAY */ | ||||
|   *n = nread; | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The public read function reads from the 'sockfd' file descriptor only. | ||||
|  * Use the Curl_read() internally when you want to specify fd. | ||||
|  */ | ||||
|  | ||||
| CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, | ||||
|                    ssize_t *n) | ||||
| { | ||||
|   struct connectdata *conn = (struct connectdata *)c_conn; | ||||
|  | ||||
|   if(!n || !conn || (conn->handle != STRUCT_CONNECT)) | ||||
|     return CURLE_FAILED_INIT; | ||||
|  | ||||
|   return Curl_read(conn, conn->sockfd, buf, buffersize, n); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										14
									
								
								lib/sendf.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								lib/sendf.h
									
									
									
									
									
								
							| @@ -23,13 +23,10 @@ | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| size_t Curl_sendf(int fd, struct UrlData *, char *fmt, ...); | ||||
| size_t Curl_ssend(int fd, struct connectdata *, void *fmt, size_t len); | ||||
| size_t Curl_sendf(int fd, struct connectdata *, char *fmt, ...); | ||||
| void Curl_infof(struct UrlData *, char *fmt, ...); | ||||
| void Curl_failf(struct UrlData *, char *fmt, ...); | ||||
|  | ||||
| #define sendf Curl_sendf | ||||
| #define ssend Curl_ssend | ||||
| #define infof Curl_infof | ||||
| #define failf Curl_failf | ||||
|  | ||||
| @@ -47,4 +44,13 @@ typedef struct send_buffer send_buffer; | ||||
| CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr, | ||||
|                            size_t len); | ||||
|  | ||||
| /* internal read-function, does plain socket, SSL and krb4 */ | ||||
| CURLcode Curl_read(struct connectdata *conn, int sockfd, | ||||
|                    char *buf, size_t buffersize, | ||||
|                    ssize_t *n); | ||||
| /* internal write-function, does plain socket, SSL and krb4 */ | ||||
| CURLcode Curl_write(struct connectdata *conn, int sockfd, | ||||
|                     void *mem, size_t len, | ||||
|                     size_t *written); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -100,7 +100,6 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO) | ||||
|    1. close a socket | ||||
|    2. read from a socket | ||||
|    3. write to a socket | ||||
|    (Hopefully, only win32-crap do this weird name changing) | ||||
|  | ||||
|    4. set the SIGALRM signal timeout | ||||
|    5. set dir/file naming defines | ||||
| @@ -115,8 +114,8 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO) | ||||
| #else | ||||
|      /* gcc-for-win is still good :) */ | ||||
| #define sclose(x) close(x) | ||||
| #define sread(x,y,z) read(x,y,z) | ||||
| #define swrite(x,y,z) write(x,y,z) | ||||
| #define sread(x,y,z) recv(x,y,z,0) | ||||
| #define swrite(x,y,z) send(x,y,z,0) | ||||
| #define myalarm(x) alarm(x) | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										52
									
								
								lib/ssluse.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								lib/ssluse.c
									
									
									
									
									
								
							| @@ -64,6 +64,7 @@ static int passwd_callback(char *buf, int num, int verify | ||||
|  | ||||
| static | ||||
| int cert_stuff(struct UrlData *data,  | ||||
|                struct connectdata *conn, | ||||
|                char *cert_file, | ||||
|                char *key_file) | ||||
| { | ||||
| @@ -78,10 +79,10 @@ int cert_stuff(struct UrlData *data, | ||||
|        */ | ||||
|       strcpy(global_passwd, data->cert_passwd); | ||||
|       /* Set passwd callback: */ | ||||
|       SSL_CTX_set_default_passwd_cb(data->ssl.ctx, passwd_callback); | ||||
|       SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback); | ||||
|     } | ||||
|  | ||||
|     if (SSL_CTX_use_certificate_file(data->ssl.ctx, | ||||
|     if (SSL_CTX_use_certificate_file(conn->ssl.ctx, | ||||
| 				     cert_file, | ||||
| 				     SSL_FILETYPE_PEM) <= 0) { | ||||
|       failf(data, "unable to set certificate file (wrong password?)\n"); | ||||
| @@ -90,14 +91,14 @@ int cert_stuff(struct UrlData *data, | ||||
|     if (key_file == NULL) | ||||
|       key_file=cert_file; | ||||
|  | ||||
|     if (SSL_CTX_use_PrivateKey_file(data->ssl.ctx, | ||||
|     if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx, | ||||
| 				    key_file, | ||||
| 				    SSL_FILETYPE_PEM) <= 0) { | ||||
|       failf(data, "unable to set public key file\n"); | ||||
|       return(0); | ||||
|     } | ||||
|      | ||||
|     ssl=SSL_new(data->ssl.ctx); | ||||
|     ssl=SSL_new(conn->ssl.ctx); | ||||
|     x509=SSL_get_certificate(ssl); | ||||
|      | ||||
|     if (x509 != NULL) | ||||
| @@ -111,7 +112,7 @@ int cert_stuff(struct UrlData *data, | ||||
|      | ||||
|     /* Now we know that a key and cert have been set against | ||||
|      * the SSL context */ | ||||
|     if (!SSL_CTX_check_private_key(data->ssl.ctx)) { | ||||
|     if (!SSL_CTX_check_private_key(conn->ssl.ctx)) { | ||||
|       failf(data, "Private key does not match the certificate public key\n"); | ||||
|       return(0); | ||||
|     } | ||||
| @@ -141,15 +142,16 @@ int cert_verify_callback(int ok, X509_STORE_CTX *ctx) | ||||
|  | ||||
| /* ====================================================== */ | ||||
| int | ||||
| Curl_SSLConnect (struct UrlData *data) | ||||
| Curl_SSLConnect(struct connectdata *conn) | ||||
| { | ||||
| #ifdef USE_SSLEAY | ||||
|   struct UrlData *data = conn->data; | ||||
|   int err; | ||||
|   char * str; | ||||
|   SSL_METHOD *req_method; | ||||
|  | ||||
|   /* mark this is being ssl enabled from here on out. */ | ||||
|     data->ssl.use = TRUE; | ||||
|   conn->ssl.use = TRUE; | ||||
|  | ||||
|   /* Lets get nice error messages */ | ||||
|   SSL_load_error_strings(); | ||||
| @@ -192,26 +194,26 @@ Curl_SSLConnect (struct UrlData *data) | ||||
|     break; | ||||
|   } | ||||
|      | ||||
|     data->ssl.ctx = SSL_CTX_new(req_method); | ||||
|   conn->ssl.ctx = SSL_CTX_new(req_method); | ||||
|  | ||||
|     if(!data->ssl.ctx) { | ||||
|   if(!conn->ssl.ctx) { | ||||
|     failf(data, "SSL: couldn't create a context!"); | ||||
|     return 1; | ||||
|   } | ||||
|      | ||||
|   if(data->cert) { | ||||
|       if (!cert_stuff(data, data->cert, data->cert)) { | ||||
|     if (!cert_stuff(data, conn, data->cert, data->cert)) { | ||||
|       failf(data, "couldn't use certificate!\n"); | ||||
|       return 2; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if(data->ssl.verifypeer){ | ||||
|       SSL_CTX_set_verify(data->ssl.ctx, | ||||
|     SSL_CTX_set_verify(conn->ssl.ctx, | ||||
|                        SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| | ||||
|                        SSL_VERIFY_CLIENT_ONCE, | ||||
|                        cert_verify_callback); | ||||
|       if (!SSL_CTX_load_verify_locations(data->ssl.ctx, | ||||
|     if (!SSL_CTX_load_verify_locations(conn->ssl.ctx, | ||||
|                                        data->ssl.CAfile, | ||||
|                                        data->ssl.CApath)) { | ||||
|       failf(data,"error setting cerficate verify locations\n"); | ||||
| @@ -219,18 +221,18 @@ Curl_SSLConnect (struct UrlData *data) | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|       SSL_CTX_set_verify(data->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback); | ||||
|     SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback); | ||||
|  | ||||
|  | ||||
|   /* Lets make an SSL structure */ | ||||
|     data->ssl.handle = SSL_new (data->ssl.ctx); | ||||
|     SSL_set_connect_state (data->ssl.handle); | ||||
|   conn->ssl.handle = SSL_new (conn->ssl.ctx); | ||||
|   SSL_set_connect_state (conn->ssl.handle); | ||||
|  | ||||
|     data->ssl.server_cert = 0x0; | ||||
|   conn->ssl.server_cert = 0x0; | ||||
|  | ||||
|   /* pass the raw socket into the SSL layers */ | ||||
|     SSL_set_fd (data->ssl.handle, data->firstsocket); | ||||
|     err = SSL_connect (data->ssl.handle); | ||||
|   SSL_set_fd (conn->ssl.handle, conn->firstsocket); | ||||
|   err = SSL_connect (conn->ssl.handle); | ||||
|  | ||||
|   if (-1 == err) { | ||||
|     err = ERR_get_error();  | ||||
| @@ -240,7 +242,7 @@ Curl_SSLConnect (struct UrlData *data) | ||||
|  | ||||
|   /* Informational message */ | ||||
|   infof (data, "SSL connection using %s\n", | ||||
|            SSL_get_cipher(data->ssl.handle)); | ||||
|          SSL_get_cipher(conn->ssl.handle)); | ||||
|    | ||||
|   /* Get server's certificate (note: beware of dynamic allocation) - opt */ | ||||
|   /* major serious hack alert -- we should check certificates | ||||
| @@ -248,14 +250,14 @@ Curl_SSLConnect (struct UrlData *data) | ||||
|    * attack | ||||
|    */ | ||||
|  | ||||
|     data->ssl.server_cert = SSL_get_peer_certificate (data->ssl.handle); | ||||
|     if(!data->ssl.server_cert) { | ||||
|   conn->ssl.server_cert = SSL_get_peer_certificate (conn->ssl.handle); | ||||
|   if(!conn->ssl.server_cert) { | ||||
|     failf(data, "SSL: couldn't get peer certificate!"); | ||||
|     return 3; | ||||
|   } | ||||
|   infof (data, "Server certificate:\n"); | ||||
|    | ||||
|     str = X509_NAME_oneline (X509_get_subject_name (data->ssl.server_cert), | ||||
|   str = X509_NAME_oneline (X509_get_subject_name (conn->ssl.server_cert), | ||||
|                            NULL, 0); | ||||
|   if(!str) { | ||||
|     failf(data, "SSL: couldn't get X509-subject!"); | ||||
| @@ -264,7 +266,7 @@ Curl_SSLConnect (struct UrlData *data) | ||||
|   infof(data, "\t subject: %s\n", str); | ||||
|   CRYPTO_free(str); | ||||
|  | ||||
|     str = X509_NAME_oneline (X509_get_issuer_name  (data->ssl.server_cert), | ||||
|   str = X509_NAME_oneline (X509_get_issuer_name  (conn->ssl.server_cert), | ||||
|                            NULL, 0); | ||||
|   if(!str) { | ||||
|     failf(data, "SSL: couldn't get X509-issuer name!"); | ||||
| @@ -277,13 +279,13 @@ Curl_SSLConnect (struct UrlData *data) | ||||
|      deallocating the certificate. */ | ||||
|  | ||||
|   if(data->ssl.verifypeer) { | ||||
|       data->ssl.certverifyresult=SSL_get_verify_result(data->ssl.handle); | ||||
|     data->ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle); | ||||
|     infof(data, "Verify result: %d\n", data->ssl.certverifyresult); | ||||
|   } | ||||
|   else | ||||
|     data->ssl.certverifyresult=0; | ||||
|  | ||||
|     X509_free(data->ssl.server_cert); | ||||
|   X509_free(conn->ssl.server_cert); | ||||
| #else /* USE_SSLEAY */ | ||||
|   /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */ | ||||
|   (void) data; | ||||
|   | ||||
| @@ -22,5 +22,6 @@ | ||||
|  * | ||||
|  * $Id$ | ||||
|  *****************************************************************************/ | ||||
| int Curl_SSLConnect (struct UrlData *data); | ||||
| #include "urldata.h" | ||||
| int Curl_SSLConnect(struct connectdata *conn); | ||||
| #endif | ||||
|   | ||||
| @@ -66,3 +66,44 @@ int Curl_strnequal(const char *first, const char *second, size_t max) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #ifndef HAVE_STRLCAT | ||||
| /* | ||||
|  * The strlcat() function appends the NUL-terminated string src to the end | ||||
|  * of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi- | ||||
|  * nating the result. | ||||
|  * | ||||
|  * The strlcpy() and strlcat() functions return the total length of the | ||||
|  * string they tried to create.  For strlcpy() that means the length of src. | ||||
|  * For strlcat() that means the initial length of dst plus the length of | ||||
|  * src. While this may seem somewhat confusing it was done to make trunca- | ||||
|  * tion detection simple. | ||||
|  * | ||||
|  *  | ||||
|  */ | ||||
| size_t strlcat(char *dst, const char *src, size_t siz) | ||||
| { | ||||
|   char *d = dst; | ||||
|   const char *s = src; | ||||
|   size_t n = siz; | ||||
|   size_t dlen; | ||||
|  | ||||
|   /* Find the end of dst and adjust bytes left but don't go past end */ | ||||
|   while (n-- != 0 && *d != '\0') | ||||
|     d++; | ||||
|   dlen = d - dst; | ||||
|   n = siz - dlen; | ||||
|  | ||||
|   if (n == 0) | ||||
|     return(dlen + strlen(s)); | ||||
|   while (*s != '\0') { | ||||
|     if (n != 1) { | ||||
|       *d++ = *s; | ||||
|       n--; | ||||
|     } | ||||
|     s++; | ||||
|   } | ||||
|   *d = '\0'; | ||||
|  | ||||
|   return(dlen + (s - src));	/* count does not include NUL */ | ||||
| } | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										376
									
								
								lib/telnet.c
									
									
									
									
									
								
							
							
						
						
									
										376
									
								
								lib/telnet.c
									
									
									
									
									
								
							| @@ -73,8 +73,6 @@ | ||||
| #include <curl/curl.h> | ||||
| #include "transfer.h" | ||||
| #include "sendf.h" | ||||
| #include "formdata.h" | ||||
| #include "progress.h" | ||||
|  | ||||
| #define _MPRINTF_REPLACE /* use our functions only */ | ||||
| #include <curl/mprintf.h> | ||||
| @@ -98,12 +96,7 @@ | ||||
| #define  SB_LEN() (subend - subpointer) | ||||
|  | ||||
| static | ||||
| void telwrite(struct UrlData *data, | ||||
| 	      unsigned char *buffer,	/* Data to write */ | ||||
| 	      int count);		/* Number of bytes to write */ | ||||
|  | ||||
| static | ||||
| void telrcv(struct UrlData *data, | ||||
| void telrcv(struct connectdata *, | ||||
| 	    unsigned char *inbuf,	/* Data received from socket */ | ||||
| 	    int count);			/* Number of bytes received */ | ||||
|  | ||||
| @@ -111,14 +104,14 @@ static void printoption(struct UrlData *data, | ||||
| 			const char *direction, | ||||
| 			int cmd, int option); | ||||
|  | ||||
| static void negotiate(struct UrlData *data); | ||||
| static void send_negotiation(struct UrlData *data, int cmd, int option); | ||||
| static void set_local_option(struct UrlData *data, int cmd, int option); | ||||
| static void set_remote_option(struct UrlData *data, int cmd, int option); | ||||
| static void negotiate(struct connectdata *); | ||||
| static void send_negotiation(struct connectdata *, int cmd, int option); | ||||
| static void set_local_option(struct connectdata *, int cmd, int option); | ||||
| static void set_remote_option(struct connectdata *, int cmd, int option); | ||||
|  | ||||
| static void printsub(struct UrlData *data, | ||||
| 		     int direction, unsigned char *pointer, int length); | ||||
| static void suboption(struct UrlData *data); | ||||
| static void suboption(struct connectdata *); | ||||
|  | ||||
| /* suboptions */ | ||||
| static char subbuffer[SUBBUFSIZE]; | ||||
| @@ -149,6 +142,8 @@ static enum | ||||
| #define EMPTY	 0 | ||||
| #define OPPOSITE 1 | ||||
|  | ||||
| static int please_negotiate = 0; | ||||
| static int already_negotiated = 0; | ||||
| static int us[256];  | ||||
| static int usq[256];  | ||||
| static int us_preferred[256];  | ||||
| @@ -156,8 +151,12 @@ static int him[256]; | ||||
| static int himq[256];  | ||||
| static int him_preferred[256];  | ||||
|  | ||||
| static char *subopt_ttype = NULL; /* Set with suboption TTYPE */ | ||||
| static char *subopt_xdisploc = NULL; /* Set with suboption XDISPLOC */ | ||||
| static struct curl_slist *telnet_vars = NULL; /* Environment variables */ | ||||
|  | ||||
| static | ||||
| void init_telnet(struct UrlData *data) | ||||
| void init_telnet(struct connectdata *conn) | ||||
| { | ||||
|   telrcv_state = TS_DATA; | ||||
|  | ||||
| @@ -172,27 +171,24 @@ void init_telnet(struct UrlData *data) | ||||
|   memset(himq, NO, 256); | ||||
|   memset(him_preferred, NO, 256); | ||||
|  | ||||
|    /* Set the options we want */ | ||||
|   /* Set the options we want by default */ | ||||
|   us_preferred[TELOPT_BINARY] = YES; | ||||
|   us_preferred[TELOPT_SGA] = YES; | ||||
|   him_preferred[TELOPT_BINARY] = YES; | ||||
|   him_preferred[TELOPT_SGA] = YES; | ||||
|  | ||||
|    /* Start negotiating */ | ||||
|    negotiate(data); | ||||
| } | ||||
|  | ||||
| static void negotiate(struct UrlData *data) | ||||
| static void negotiate(struct connectdata *conn) | ||||
| { | ||||
|   int i; | ||||
|     | ||||
|   for(i = 0;i < NTELOPTS;i++) | ||||
|   { | ||||
|     if(us_preferred[i] == YES) | ||||
| 	 set_local_option(data, i, YES); | ||||
|       set_local_option(conn, i, YES); | ||||
|        | ||||
|     if(him_preferred[i] == YES) | ||||
| 	 set_remote_option(data, i, YES); | ||||
|       set_remote_option(conn, i, YES); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -235,7 +231,7 @@ static void printoption(struct UrlData *data, | ||||
|   } | ||||
| } | ||||
|  | ||||
| static void send_negotiation(struct UrlData *data, int cmd, int option) | ||||
| static void send_negotiation(struct connectdata *conn, int cmd, int option) | ||||
| { | ||||
|    unsigned char buf[3]; | ||||
|  | ||||
| @@ -243,13 +239,13 @@ static void send_negotiation(struct UrlData *data, int cmd, int option) | ||||
|    buf[1] = cmd; | ||||
|    buf[2] = option; | ||||
|     | ||||
|    swrite(data->firstsocket, buf, 3); | ||||
|    swrite(conn->firstsocket, buf, 3); | ||||
|     | ||||
|    printoption(data, "SENT", cmd, option); | ||||
|    printoption(conn->data, "SENT", cmd, option); | ||||
| } | ||||
|  | ||||
| static | ||||
| void set_remote_option(struct UrlData *data, int option, int newstate) | ||||
| void set_remote_option(struct connectdata *conn, int option, int newstate) | ||||
| { | ||||
|   if(newstate == YES) | ||||
|   { | ||||
| @@ -257,7 +253,7 @@ void set_remote_option(struct UrlData *data, int option, int newstate) | ||||
|     { | ||||
|       case NO: | ||||
|         him[option] = WANTYES; | ||||
| 	 send_negotiation(data, DO, option); | ||||
|         send_negotiation(conn, DO, option); | ||||
|         break; | ||||
| 	  | ||||
|       case YES: | ||||
| @@ -300,7 +296,7 @@ void set_remote_option(struct UrlData *data, int option, int newstate) | ||||
| 	  | ||||
|       case YES: | ||||
|         him[option] = WANTNO; | ||||
| 	 send_negotiation(data, DONT, option); | ||||
|         send_negotiation(conn, DONT, option); | ||||
|         break; | ||||
| 	  | ||||
|       case WANTNO: | ||||
| @@ -330,7 +326,7 @@ void set_remote_option(struct UrlData *data, int option, int newstate) | ||||
| } | ||||
|  | ||||
| static | ||||
| void rec_will(struct UrlData *data, int option) | ||||
| void rec_will(struct connectdata *conn, int option) | ||||
| { | ||||
|   switch(him[option]) | ||||
|   { | ||||
| @@ -338,11 +334,11 @@ void rec_will(struct UrlData *data, int option) | ||||
|       if(him_preferred[option] == YES) | ||||
|       { | ||||
|         him[option] = YES; | ||||
| 	 send_negotiation(data, DO, option); | ||||
|         send_negotiation(conn, DO, option); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
| 	 send_negotiation(data, DONT, option); | ||||
|         send_negotiation(conn, DONT, option); | ||||
|       } | ||||
|       break; | ||||
| 	  | ||||
| @@ -374,7 +370,7 @@ void rec_will(struct UrlData *data, int option) | ||||
|         case OPPOSITE: | ||||
|           him[option] = WANTNO; | ||||
|           himq[option] = EMPTY; | ||||
| 	 send_negotiation(data, DONT, option); | ||||
|           send_negotiation(conn, DONT, option); | ||||
|           break; | ||||
|       } | ||||
|       break; | ||||
| @@ -382,7 +378,7 @@ void rec_will(struct UrlData *data, int option) | ||||
| } | ||||
|     | ||||
| static | ||||
| void rec_wont(struct UrlData *data, int option) | ||||
| void rec_wont(struct connectdata *conn, int option) | ||||
| { | ||||
|   switch(him[option]) | ||||
|   { | ||||
| @@ -392,7 +388,7 @@ void rec_wont(struct UrlData *data, int option) | ||||
| 	  | ||||
|     case YES: | ||||
|       him[option] = NO; | ||||
|       send_negotiation(data, DONT, option); | ||||
|       send_negotiation(conn, DONT, option); | ||||
|       break; | ||||
| 	  | ||||
|     case WANTNO: | ||||
| @@ -405,7 +401,7 @@ void rec_wont(struct UrlData *data, int option) | ||||
|         case OPPOSITE: | ||||
|           him[option] = WANTYES; | ||||
|           himq[option] = EMPTY; | ||||
| 	 send_negotiation(data, DO, option); | ||||
|           send_negotiation(conn, DO, option); | ||||
|           break; | ||||
|       } | ||||
|       break; | ||||
| @@ -425,7 +421,7 @@ void rec_wont(struct UrlData *data, int option) | ||||
|   } | ||||
| } | ||||
|     | ||||
| void set_local_option(struct UrlData *data, int option, int newstate) | ||||
| void set_local_option(struct connectdata *conn, int option, int newstate) | ||||
| { | ||||
|   if(newstate == YES) | ||||
|   { | ||||
| @@ -433,7 +429,7 @@ void set_local_option(struct UrlData *data, int option, int newstate) | ||||
|     { | ||||
|       case NO: | ||||
|         us[option] = WANTYES; | ||||
| 	 send_negotiation(data, WILL, option); | ||||
|         send_negotiation(conn, WILL, option); | ||||
|         break; | ||||
| 	  | ||||
|       case YES: | ||||
| @@ -476,7 +472,7 @@ void set_local_option(struct UrlData *data, int option, int newstate) | ||||
| 	  | ||||
|       case YES: | ||||
|         us[option] = WANTNO; | ||||
| 	 send_negotiation(data, WONT, option); | ||||
|         send_negotiation(conn, WONT, option); | ||||
|         break; | ||||
| 	  | ||||
|       case WANTNO: | ||||
| @@ -506,7 +502,7 @@ void set_local_option(struct UrlData *data, int option, int newstate) | ||||
| } | ||||
|  | ||||
| static | ||||
| void rec_do(struct UrlData *data, int option) | ||||
| void rec_do(struct connectdata *conn, int option) | ||||
| { | ||||
|   switch(us[option]) | ||||
|   { | ||||
| @@ -514,11 +510,11 @@ void rec_do(struct UrlData *data, int option) | ||||
|       if(us_preferred[option] == YES) | ||||
|       { | ||||
|         us[option] = YES; | ||||
| 	 send_negotiation(data, WILL, option); | ||||
|         send_negotiation(conn, WILL, option); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
| 	 send_negotiation(data, WONT, option); | ||||
|         send_negotiation(conn, WONT, option); | ||||
|       } | ||||
|       break; | ||||
| 	  | ||||
| @@ -550,7 +546,7 @@ void rec_do(struct UrlData *data, int option) | ||||
|         case OPPOSITE: | ||||
|           us[option] = WANTNO; | ||||
|           himq[option] = EMPTY; | ||||
| 	 send_negotiation(data, WONT, option); | ||||
|           send_negotiation(conn, WONT, option); | ||||
|           break; | ||||
|       } | ||||
|       break; | ||||
| @@ -558,7 +554,7 @@ void rec_do(struct UrlData *data, int option) | ||||
| } | ||||
|  | ||||
| static    | ||||
| void rec_dont(struct UrlData *data, int option) | ||||
| void rec_dont(struct connectdata *conn, int option) | ||||
| { | ||||
|   switch(us[option]) | ||||
|   { | ||||
| @@ -568,7 +564,7 @@ void rec_dont(struct UrlData *data, int option) | ||||
| 	  | ||||
|     case YES: | ||||
|       us[option] = NO; | ||||
|       send_negotiation(data, WONT, option); | ||||
|       send_negotiation(conn, WONT, option); | ||||
|       break; | ||||
| 	  | ||||
|     case WANTNO: | ||||
| @@ -581,7 +577,7 @@ void rec_dont(struct UrlData *data, int option) | ||||
|         case OPPOSITE: | ||||
|           us[option] = WANTYES; | ||||
|           usq[option] = EMPTY; | ||||
| 	 send_negotiation(data, WILL, option); | ||||
|           send_negotiation(conn, WILL, option); | ||||
|           break; | ||||
|       } | ||||
|       break; | ||||
| @@ -606,7 +602,6 @@ static void printsub(struct UrlData *data, | ||||
| 		     int direction,		/* '<' or '>' */ | ||||
| 		     unsigned char *pointer,	/* where suboption data is */ | ||||
| 		     int length)		/* length of suboption data */ | ||||
|  | ||||
| { | ||||
|   int i = 0; | ||||
|  | ||||
| @@ -648,12 +643,65 @@ static void printsub(struct UrlData *data, | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|       if (TELOPT_OK(pointer[0])) | ||||
| 	 printf("%s (unknown)", TELOPT(pointer[0])); | ||||
|     if (TELOPT_OK(pointer[0])) { | ||||
|       switch(pointer[0]) { | ||||
|         case TELOPT_TTYPE: | ||||
|         case TELOPT_XDISPLOC: | ||||
|         case TELOPT_NEW_ENVIRON: | ||||
|           printf("%s", TELOPT(pointer[0])); | ||||
|           break; | ||||
|         default: | ||||
|           printf("%s (unsupported)", TELOPT(pointer[0])); | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|       printf("%d (unknown)", pointer[i]); | ||||
|       for (i = 1; i < length; i++) | ||||
| 	 printf(" %d", pointer[i]); | ||||
|  | ||||
|     switch(pointer[1]) { | ||||
|       case TELQUAL_IS: | ||||
|         printf(" IS"); | ||||
|         break; | ||||
|       case TELQUAL_SEND: | ||||
|         printf(" SEND"); | ||||
|         break; | ||||
|       case TELQUAL_INFO: | ||||
|         printf(" INFO/REPLY"); | ||||
|         break; | ||||
|       case TELQUAL_NAME: | ||||
|         printf(" NAME"); | ||||
|         break; | ||||
|     } | ||||
|        | ||||
|     switch(pointer[0]) { | ||||
|       case TELOPT_TTYPE: | ||||
|       case TELOPT_XDISPLOC: | ||||
|         pointer[length] = 0; | ||||
|         printf(" \"%s\"", &pointer[2]); | ||||
|         break; | ||||
|       case TELOPT_NEW_ENVIRON: | ||||
|         if(pointer[1] == TELQUAL_IS) { | ||||
|           printf(" "); | ||||
|           for(i = 3;i < length;i++) { | ||||
|             switch(pointer[i]) { | ||||
|               case NEW_ENV_VAR: | ||||
|                 printf(", "); | ||||
|                 break; | ||||
|               case NEW_ENV_VALUE: | ||||
|                 printf(" = "); | ||||
|                 break; | ||||
|               default: | ||||
|                 printf("%c", pointer[i]); | ||||
|                 break; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|         break; | ||||
|       default: | ||||
|         for (i = 2; i < length; i++) | ||||
|           printf(" %.2x", pointer[i]); | ||||
|         break; | ||||
|     } | ||||
|        | ||||
|     if (direction) | ||||
|     { | ||||
| @@ -662,6 +710,64 @@ static void printsub(struct UrlData *data, | ||||
|   } | ||||
| } | ||||
|  | ||||
| static int check_telnet_options(struct connectdata *conn) | ||||
| { | ||||
|   struct curl_slist *head; | ||||
|   char option_keyword[128]; | ||||
|   char option_arg[256]; | ||||
|   char *buf; | ||||
|   struct UrlData *data = conn->data; | ||||
|  | ||||
|   /* Add the user name as an environment variable if it | ||||
|      was given on the command line */ | ||||
|   if(data->bits.user_passwd) | ||||
|   { | ||||
|     char *buf = malloc(256); | ||||
|     sprintf(buf, "USER,%s", data->user); | ||||
|     telnet_vars = curl_slist_append(telnet_vars, buf); | ||||
|  | ||||
|     us_preferred[TELOPT_NEW_ENVIRON] = YES; | ||||
|   } | ||||
|  | ||||
|   for(head = data->telnet_options; head; head=head->next) { | ||||
|     if(sscanf(head->data, "%127[^= ]%*[ =]%255s", | ||||
|               option_keyword, option_arg) == 2) { | ||||
|  | ||||
|       /* Terminal type */ | ||||
|       if(strequal(option_keyword, "TTYPE")) { | ||||
|         subopt_ttype = option_arg; | ||||
|         us_preferred[TELOPT_TTYPE] = YES; | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       /* Display variable */ | ||||
|       if(strequal(option_keyword, "XDISPLOC")) { | ||||
|         subopt_xdisploc = option_arg; | ||||
|         us_preferred[TELOPT_XDISPLOC] = YES; | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       /* Environment variable */ | ||||
|       if(strequal(option_keyword, "NEW_ENV")) { | ||||
|         buf = strdup(option_arg); | ||||
|         if(!buf) | ||||
|           return CURLE_OUT_OF_MEMORY; | ||||
|         telnet_vars = curl_slist_append(telnet_vars, buf); | ||||
|         us_preferred[TELOPT_NEW_ENVIRON] = YES; | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       failf(data, "Unknown telnet option %s", head->data); | ||||
|       return CURLE_UNKNOWN_TELNET_OPTION; | ||||
|     } else { | ||||
|       failf(data, "Syntax error in telnet option: %s", head->data); | ||||
|       return CURLE_TELNET_OPTION_SYNTAX; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * suboption() | ||||
|  * | ||||
| @@ -670,19 +776,69 @@ static void printsub(struct UrlData *data, | ||||
|  * No suboptions are supported yet. | ||||
|  */ | ||||
|  | ||||
| static void suboption(struct UrlData *data) | ||||
| static void suboption(struct connectdata *conn) | ||||
| { | ||||
|   struct curl_slist *v; | ||||
|   unsigned char subchar; | ||||
|   unsigned char temp[2048]; | ||||
|   int len; | ||||
|   int tmplen; | ||||
|   char varname[128]; | ||||
|   char varval[128]; | ||||
|   struct UrlData *data = conn->data; | ||||
|  | ||||
|   printsub(data, '<', (unsigned char *)subbuffer, SB_LEN()+2); | ||||
|   switch (subchar = SB_GET()) { | ||||
|     case TELOPT_TTYPE: | ||||
|       len = strlen(subopt_ttype) + 4 + 2; | ||||
|       snprintf((char *)temp, sizeof(temp), | ||||
|                "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, | ||||
|                TELQUAL_IS, subopt_ttype, IAC, SE); | ||||
|       swrite(conn->firstsocket, temp, len); | ||||
|       printsub(data, '>', &temp[2], len-2); | ||||
|       break; | ||||
|     case TELOPT_XDISPLOC: | ||||
|       len = strlen(subopt_xdisploc) + 4 + 2; | ||||
|       snprintf((char *)temp, sizeof(temp), | ||||
|                "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC, | ||||
|                TELQUAL_IS, subopt_xdisploc, IAC, SE); | ||||
|       swrite(conn->firstsocket, temp, len); | ||||
|       printsub(data, '>', &temp[2], len-2); | ||||
|       break; | ||||
|     case TELOPT_NEW_ENVIRON: | ||||
|       snprintf((char *)temp, sizeof(temp), | ||||
|                "%c%c%c%c", IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_IS); | ||||
|       len = 4; | ||||
|  | ||||
|       for(v = telnet_vars;v;v = v->next) { | ||||
|         tmplen = (strlen(v->data) + 1); | ||||
|         /* Add the variable only if it fits */ | ||||
|         if(len + tmplen < sizeof(temp)-6) { | ||||
|           sscanf(v->data, "%127[^,],%s", varname, varval); | ||||
|           snprintf((char *)&temp[len], sizeof(temp) - len, | ||||
|                    "%c%s%c%s", NEW_ENV_VAR, varname, | ||||
|                    NEW_ENV_VALUE, varval); | ||||
|           len += tmplen; | ||||
|         } | ||||
|       } | ||||
|       snprintf((char *)&temp[len], sizeof(temp) - len, | ||||
|                "%c%c", IAC, SE); | ||||
|       len += 2; | ||||
|       swrite(conn->firstsocket, temp, len); | ||||
|       printsub(data, '>', &temp[2], len-2); | ||||
|       break; | ||||
|   } | ||||
|   return; | ||||
| } | ||||
|  | ||||
| static | ||||
| void telrcv(struct UrlData *data, | ||||
| void telrcv(struct connectdata *conn, | ||||
|             unsigned char *inbuf,	/* Data received from socket */ | ||||
|             int count)			/* Number of bytes received */ | ||||
| { | ||||
|   unsigned char c; | ||||
|   int index = 0; | ||||
|   struct UrlData *data = conn->data; | ||||
|  | ||||
|   while(count--) | ||||
|   { | ||||
| @@ -749,25 +905,29 @@ void telrcv(struct UrlData *data, | ||||
|  | ||||
|       case TS_WILL: | ||||
|         printoption(data, "RCVD", WILL, c); | ||||
| 	 rec_will(data, c); | ||||
|         please_negotiate = 1; | ||||
|         rec_will(conn, c); | ||||
|         telrcv_state = TS_DATA; | ||||
|         continue; | ||||
|        | ||||
|       case TS_WONT: | ||||
|         printoption(data, "RCVD", WONT, c); | ||||
| 	 rec_wont(data, c); | ||||
|         please_negotiate = 1; | ||||
|         rec_wont(conn, c); | ||||
|         telrcv_state = TS_DATA; | ||||
|         continue; | ||||
|        | ||||
|       case TS_DO: | ||||
|         printoption(data, "RCVD", DO, c); | ||||
| 	 rec_do(data, c); | ||||
|         please_negotiate = 1; | ||||
|         rec_do(conn, c); | ||||
|         telrcv_state = TS_DATA; | ||||
|         continue; | ||||
|        | ||||
|       case TS_DONT: | ||||
|         printoption(data, "RCVD", DONT, c); | ||||
| 	 rec_dont(data, c); | ||||
|         please_negotiate = 1; | ||||
|         rec_dont(conn, c); | ||||
|         telrcv_state = TS_DATA; | ||||
|         continue; | ||||
|  | ||||
| @@ -805,7 +965,7 @@ void telrcv(struct UrlData *data, | ||||
|             SB_TERM(); | ||||
| 	     | ||||
|             printoption(data, "In SUBOPTION processing, RCVD", IAC, c); | ||||
| 	       suboption(data);   /* handle sub-option */ | ||||
|             suboption(conn);   /* handle sub-option */ | ||||
|             telrcv_state = TS_IAC; | ||||
|             goto process_iac; | ||||
|           } | ||||
| @@ -818,7 +978,7 @@ void telrcv(struct UrlData *data, | ||||
|           SB_ACCUM((unsigned char)SE); | ||||
|           subpointer -= 2; | ||||
|           SB_TERM(); | ||||
| 	    suboption(data);   /* handle sub-option */ | ||||
|           suboption(conn);   /* handle sub-option */ | ||||
|           telrcv_state = TS_DATA; | ||||
|         } | ||||
|         break; | ||||
| @@ -826,53 +986,29 @@ void telrcv(struct UrlData *data, | ||||
|   } | ||||
| } | ||||
|  | ||||
| static | ||||
| void telwrite(struct UrlData *data, | ||||
| 	      unsigned char *buffer,	/* Data to write */ | ||||
| 	      int count)		/* Number of bytes to write */ | ||||
| { | ||||
|    unsigned char outbuf[2]; | ||||
|    int out_count = 0; | ||||
|    int bytes_written; | ||||
|  | ||||
|    while(count--) | ||||
|    { | ||||
|       outbuf[0] = *buffer++; | ||||
|       out_count = 1; | ||||
|       if(outbuf[0] == IAC) | ||||
| 	 outbuf[out_count++] = IAC; | ||||
|        | ||||
| #ifndef USE_SSLEAY | ||||
|       bytes_written = swrite(data->firstsocket, outbuf, out_count); | ||||
| #else | ||||
|       if (data->ssl.use) { | ||||
|         bytes_written = SSL_write(data->ssl.handle, (char *)outbuf, | ||||
|                                   out_count); | ||||
|       } | ||||
|       else { | ||||
|         bytes_written = swrite(data->firstsocket, outbuf, out_count); | ||||
|       } | ||||
| #endif /* USE_SSLEAY */ | ||||
|    } | ||||
| } | ||||
|  | ||||
| CURLcode Curl_telnet_done(struct connectdata *conn) | ||||
| { | ||||
|   curl_slist_free_all(telnet_vars); | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| CURLcode Curl_telnet(struct connectdata *conn) | ||||
| { | ||||
|   CURLcode code; | ||||
|   struct UrlData *data = conn->data; | ||||
|   int sockfd = data->firstsocket; | ||||
|   int sockfd = conn->firstsocket; | ||||
|   fd_set readfd; | ||||
|   fd_set keepfd; | ||||
|  | ||||
|   bool keepon = TRUE; | ||||
|   char *buf = data->buffer; | ||||
|   int nread; | ||||
|   ssize_t nread; | ||||
|  | ||||
|   init_telnet(data); | ||||
|   init_telnet(conn); | ||||
|     | ||||
|   code = check_telnet_options(conn); | ||||
|   if(code) | ||||
|     return code; | ||||
|    | ||||
|   FD_ZERO (&readfd);		/* clear it */ | ||||
|   FD_SET (sockfd, &readfd); | ||||
| @@ -880,37 +1016,37 @@ CURLcode Curl_telnet(struct connectdata *conn) | ||||
|  | ||||
|   keepfd = readfd; | ||||
|  | ||||
|    while (keepon) | ||||
|    { | ||||
|   while (keepon) { | ||||
|     readfd = keepfd;		/* set this every lap in the loop */ | ||||
|  | ||||
|       switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) | ||||
|       { | ||||
|     switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) { | ||||
|     case -1:			/* error, stop reading */ | ||||
|       keepon = FALSE; | ||||
|       continue; | ||||
|     case 0:			/* timeout */ | ||||
|       break; | ||||
|     default:			/* read! */ | ||||
| 	 if(FD_ISSET(1, &readfd)) | ||||
| 	 { | ||||
|       if(FD_ISSET(1, &readfd)) { /* read from stdin */ | ||||
|         unsigned char outbuf[2]; | ||||
|         int out_count = 0; | ||||
|         size_t bytes_written; | ||||
|         char *buffer = buf; | ||||
|          | ||||
|         nread = read(1, buf, 255); | ||||
| 	    telwrite(data, (unsigned char *)buf, nread); | ||||
|  | ||||
|         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); | ||||
|         } | ||||
|       } | ||||
|  | ||||
| 	 if(FD_ISSET(sockfd, &readfd)) | ||||
| 	 { | ||||
| #ifndef USE_SSLEAY | ||||
| 	    nread = sread (sockfd, buf, BUFSIZE - 1); | ||||
| #else | ||||
| 	    if (data->ssl.use) { | ||||
| 	       nread = SSL_read (data->ssl.handle, buf, BUFSIZE - 1); | ||||
| 	    } | ||||
| 	    else { | ||||
| 	       nread = sread (sockfd, buf, BUFSIZE - 1); | ||||
| 	    } | ||||
| #endif /* USE_SSLEAY */ | ||||
| 	 } | ||||
|       if(FD_ISSET(sockfd, &readfd)) { | ||||
|         Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); | ||||
|  | ||||
|         /* if we receive 0 or less here, the server closed the connection and | ||||
|            we bail out from this! */ | ||||
| @@ -919,10 +1055,18 @@ CURLcode Curl_telnet(struct connectdata *conn) | ||||
|           break; | ||||
|         } | ||||
|  | ||||
| 	 telrcv(data, (unsigned char *)buf, nread); | ||||
|       } | ||||
|    } | ||||
|    return CURLE_OK; | ||||
| } | ||||
|  | ||||
|         telrcv(conn, (unsigned char *)buf, nread); | ||||
|  | ||||
|         /* 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(please_negotiate && !already_negotiated) { | ||||
|           negotiate(conn); | ||||
|           already_negotiated = 1; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   /* mark this as "no further transfer wanted" */ | ||||
|   return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); | ||||
| } | ||||
|   | ||||
							
								
								
									
										165
									
								
								lib/transfer.c
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								lib/transfer.c
									
									
									
									
									
								
							| @@ -82,7 +82,6 @@ | ||||
| #include <curl/types.h> | ||||
| #include "netrc.h" | ||||
|  | ||||
| #include "getenv.h" | ||||
| #include "hostip.h" | ||||
| #include "transfer.h" | ||||
| #include "sendf.h" | ||||
| @@ -109,7 +108,7 @@ | ||||
| CURLcode static | ||||
| _Transfer(struct connectdata *c_conn) | ||||
| { | ||||
|   size_t nread;                 /* number of bytes read */ | ||||
|   ssize_t nread;                /* number of bytes read */ | ||||
|   int bytecount = 0;            /* total number of bytes read */ | ||||
|   int writebytecount = 0;       /* number of bytes written */ | ||||
|   long contentlength=0;         /* size of incoming data */ | ||||
| @@ -128,13 +127,12 @@ _Transfer(struct connectdata *c_conn) | ||||
|   int offset = 0;		/* possible resume offset read from the | ||||
|                                    Content-Range: header */ | ||||
|   int code = 0;			/* error code from the 'HTTP/1.? XXX' line */ | ||||
|   int httpversion = -1;         /* the last digit in the HTTP/1.1 string */ | ||||
|  | ||||
|   /* for the low speed checks: */ | ||||
|   CURLcode urg; | ||||
|   time_t timeofdoc=0; | ||||
|   long bodywrites=0; | ||||
|  | ||||
|   char newurl[URL_MAX_LENGTH];		/* buffer for Location: URL */ | ||||
|   int writetype; | ||||
|  | ||||
|   /* the highest fd we use + 1 */ | ||||
| @@ -163,6 +161,12 @@ _Transfer(struct connectdata *c_conn) | ||||
|   Curl_pgrsTime(data, TIMER_PRETRANSFER); | ||||
|   Curl_speedinit(data); | ||||
|  | ||||
|   if((conn->sockfd == -1) && | ||||
|      (conn->writesockfd == -1)) { | ||||
|     /* nothing to read, nothing to write, we're already OK! */ | ||||
|     return CURLE_OK; | ||||
|   } | ||||
|  | ||||
|   if (!conn->getheader) { | ||||
|     header = FALSE; | ||||
|     if(conn->size > 0) | ||||
| @@ -224,7 +228,7 @@ _Transfer(struct connectdata *c_conn) | ||||
|       default: | ||||
|         if((keepon & KEEP_READ) && FD_ISSET(conn->sockfd, &readfd)) { | ||||
|           /* read! */ | ||||
|           urg = curl_read(conn, buf, BUFSIZE -1, &nread); | ||||
|           urg = Curl_read(conn, conn->sockfd, buf, BUFSIZE -1, &nread); | ||||
|  | ||||
|           /* NULL terminate, allowing string ops to be used */ | ||||
|           if (0 < (signed int) nread) | ||||
| @@ -316,9 +320,9 @@ _Transfer(struct connectdata *c_conn) | ||||
|                   p++;		/* pass the \r byte */ | ||||
|                 if ('\n' == *p) | ||||
|                   p++;		/* pass the \n byte */ | ||||
|  | ||||
| #if 0 /* headers are not included in the size */ | ||||
|                 Curl_pgrsSetDownloadSize(data, conn->size); | ||||
|  | ||||
| #endif | ||||
|                 header = FALSE;	/* no more header to parse! */ | ||||
|  | ||||
|                 /* now, only output this if the header AND body are requested: | ||||
| @@ -339,7 +343,7 @@ _Transfer(struct connectdata *c_conn) | ||||
|               if (!headerline++) { | ||||
|                 /* This is the first header, it MUST be the error code line | ||||
|                    or else we consiser this to be the body right away! */ | ||||
|                 if (sscanf (p, " HTTP/1.%*c %3d", &code)) { | ||||
|                 if (2 == sscanf (p, " HTTP/1.%d %3d", &httpversion, &code)) { | ||||
|                   /* 404 -> URL not found! */ | ||||
|                   if ( | ||||
|                       ( ((data->bits.http_follow_location) && (code >= 400)) | ||||
| @@ -363,6 +367,16 @@ _Transfer(struct connectdata *c_conn) | ||||
|               if (strnequal("Content-Length", p, 14) && | ||||
|                   sscanf (p+14, ": %ld", &contentlength)) | ||||
|                 conn->size = contentlength; | ||||
|               else if (strnequal("Connection: close", p, | ||||
|                                  strlen("Connection: close"))) { | ||||
|                 /* | ||||
|                  * [RFC 2616, section 8.1.2.1] | ||||
|                  * "Connection: close" is HTTP/1.1 language and means that | ||||
|                  * the connection will close when this request has been | ||||
|                  * served. | ||||
|                  */ | ||||
|                 conn->bits.close = TRUE; /* close when done */ | ||||
|               } | ||||
|               else if (strnequal("Content-Range", p, 13)) { | ||||
|                 if (sscanf (p+13, ": bytes %d-", &offset) || | ||||
|                     sscanf (p+13, ": bytes: %d-", &offset)) { | ||||
| @@ -389,12 +403,21 @@ _Transfer(struct connectdata *c_conn) | ||||
|               } | ||||
|               else if ((code >= 300 && code < 400) && | ||||
|                        (data->bits.http_follow_location) && | ||||
|                        strnequal("Location", p, 8) && | ||||
|                        sscanf (p+8, ": %" URL_MAX_LENGTH_TXT "s", | ||||
|                                newurl)) { | ||||
|                 /* this is the URL that the server advices us to get | ||||
|                    instead */ | ||||
|                 data->newurl = strdup (newurl); | ||||
|                        strnequal("Location: ", p, 10)) { | ||||
|                 /* this is the URL that the server advices us to get instead */ | ||||
|                 char *ptr; | ||||
|                 char *start=p; | ||||
|                 char backup; | ||||
|  | ||||
|                 start += 10; /* pass "Location: " */ | ||||
|                 ptr = start; /* start scanning here */ | ||||
|                 /* scan through the string to find the end */ | ||||
|                 while(*ptr && !isspace((int)*ptr)) | ||||
|                   ptr++; | ||||
|                 backup = *ptr; /* store the ending letter */ | ||||
|                 *ptr = '\0';   /* zero terminate */ | ||||
|                 data->newurl = strdup(start); /* clone string */ | ||||
|                 *ptr = backup; /* restore ending letter */ | ||||
|               } | ||||
|  | ||||
|               writetype = CLIENTWRITE_HEADER; | ||||
| @@ -437,17 +460,21 @@ _Transfer(struct connectdata *c_conn) | ||||
|                  write a chunk of the body */ | ||||
|               if(conn->protocol&PROT_HTTP) { | ||||
|                 /* HTTP-only checks */ | ||||
|                 if (data->resume_from && !content_range ) { | ||||
|                   /* we wanted to resume a download, although the server | ||||
|                      doesn't seem to support this */ | ||||
|                   failf (data, "HTTP server doesn't seem to support byte ranges. Cannot resume."); | ||||
|                   return CURLE_HTTP_RANGE_ERROR; | ||||
|                 } | ||||
|                 else if (data->newurl) { | ||||
|                 if (data->newurl) { | ||||
|                   /* abort after the headers if "follow Location" is set */ | ||||
|                   infof (data, "Follow to new URL: %s\n", data->newurl); | ||||
|                   return CURLE_OK; | ||||
|                 } | ||||
|                 else if (data->resume_from && | ||||
|                          !content_range && | ||||
|                          (data->httpreq==HTTPREQ_GET)) { | ||||
|                   /* we wanted to resume a download, although the server | ||||
|                      doesn't seem to support this and we did this with a GET | ||||
|                      (if it wasn't a GET we did a POST or PUT resume) */ | ||||
|                   failf (data, "HTTP server doesn't seem to support " | ||||
|                          "byte ranges. Cannot resume."); | ||||
|                   return CURLE_HTTP_RANGE_ERROR; | ||||
|                 } | ||||
|                 else if(data->timecondition && !data->range) { | ||||
|                   /* A time condition has been set AND no ranges have been | ||||
|                      requested. This seems to be what chapter 13.3.4 of | ||||
| @@ -473,13 +500,23 @@ _Transfer(struct connectdata *c_conn) | ||||
|                     } /* switch */ | ||||
|                   } /* two valid time strings */ | ||||
|                 } /* we have a time condition */ | ||||
|                 if(!conn->bits.close && (httpversion == 1)) { | ||||
|                   /* If this is not the last request before a close, we must | ||||
|                      set the maximum download size to the size of the expected | ||||
|                      document or else, we won't know when to stop reading! */ | ||||
|                   if(-1 != conn->size) | ||||
|                     conn->maxdownload = conn->size; | ||||
|  | ||||
|                   /* What to do if the size is *not* known? */ | ||||
|                 } | ||||
|  | ||||
|               } /* this is HTTP */ | ||||
|             } /* this is the first time we write a body part */ | ||||
|             bodywrites++; | ||||
|  | ||||
|             if(data->maxdownload && | ||||
|                (bytecount + nread > data->maxdownload)) { | ||||
|               nread = data->maxdownload - bytecount; | ||||
|             if(conn->maxdownload && | ||||
|                (bytecount + nread >= conn->maxdownload)) { | ||||
|               nread = conn->maxdownload - bytecount; | ||||
|               if((signed int)nread < 0 ) /* this should be unusual */ | ||||
|                 nread = 0; | ||||
|               keepon &= ~KEEP_READ; /* we're done reading */ | ||||
| @@ -534,7 +571,8 @@ _Transfer(struct connectdata *c_conn) | ||||
|           } | ||||
|  | ||||
|           /* write to socket */ | ||||
|           urg = curl_write(conn, buf, nread, &bytes_written); | ||||
|           urg = Curl_write(conn, conn->writesockfd, buf, nread, | ||||
|                            &bytes_written); | ||||
|  | ||||
|           if(nread != bytes_written) { | ||||
|             failf(data, "Failed uploading data"); | ||||
| @@ -594,12 +632,13 @@ CURLcode curl_transfer(CURL *curl) | ||||
|   CURLcode res; | ||||
|   struct UrlData *data = curl; | ||||
|   struct connectdata *c_connect=NULL; | ||||
|   bool port=TRUE; /* allow data->use_port to set port to use */ | ||||
|  | ||||
|   Curl_pgrsStartNow(data); | ||||
|  | ||||
|   do { | ||||
|     Curl_pgrsTime(data, TIMER_STARTSINGLE); | ||||
|     res = curl_connect(curl, (CURLconnect **)&c_connect); | ||||
|     res = curl_connect(curl, (CURLconnect **)&c_connect, port); | ||||
|     if(res == CURLE_OK) { | ||||
|       res = curl_do(c_connect); | ||||
|       if(res == CURLE_OK) { | ||||
| @@ -613,11 +652,17 @@ CURLcode curl_transfer(CURL *curl) | ||||
|   | ||||
|            This is assumed to happen for HTTP(S) only! | ||||
|         */ | ||||
|         char prot[16]; | ||||
|         char path[URL_MAX_LENGTH]; | ||||
|         char prot[16]; /* URL protocol string storage */ | ||||
|         char letter;   /* used for a silly sscanf */ | ||||
|  | ||||
|         port=TRUE; /* by default we use the user set port number even after | ||||
|                       a Location: */ | ||||
|  | ||||
| 	if (data->maxredirs && (data->followlocation >= data->maxredirs)) { | ||||
| 	  failf(data,"Maximum (%d) redirects followed", data->maxredirs); | ||||
| #ifdef USE_OLD_DISCONNECT | ||||
|           curl_disconnect(c_connect); | ||||
| #endif | ||||
|           res=CURLE_TOO_MANY_REDIRECTS; | ||||
| 	  break; | ||||
| 	} | ||||
| @@ -642,8 +687,7 @@ CURLcode curl_transfer(CURL *curl) | ||||
|           data->bits.http_set_referer = TRUE; /* might have been false */ | ||||
|         } | ||||
|  | ||||
|         if(2 != sscanf(data->newurl, "%15[^:]://%" URL_MAX_LENGTH_TXT | ||||
|                        "s", prot, path)) { | ||||
|         if(2 != sscanf(data->newurl, "%15[^:]://%c", prot, &letter)) { | ||||
|           /*** | ||||
|            *DANG* this is an RFC 2068 violation. The URL is supposed | ||||
|            to be absolute and this doesn't seem to be that! | ||||
| @@ -661,9 +705,10 @@ CURLcode curl_transfer(CURL *curl) | ||||
|           if(!protsep) | ||||
|             protsep=data->url; | ||||
|           else { | ||||
|             /* TBD: set the port with curl_setopt() */ | ||||
|             data->port=0; /* we got a full URL and then we should reset the | ||||
|                              port number here to re-initiate it later */ | ||||
|             port=FALSE; /* we got a full URL and thus we should not obey the | ||||
|                            port number that might have been set by the user | ||||
|                            in data->use_port */ | ||||
|  | ||||
|             protsep+=2; /* pass the slashes */ | ||||
|           } | ||||
|  | ||||
| @@ -700,9 +745,8 @@ CURLcode curl_transfer(CURL *curl) | ||||
|           data->newurl = newest; | ||||
|         } | ||||
|         else { | ||||
|           /* This was an absolute URL, clear the port number! */ | ||||
|           /* TBD: set the port with curl_setopt() */ | ||||
|           data->port = 0; | ||||
|           /* This is an absolute URL, don't use the custom port number */ | ||||
|           port = FALSE; | ||||
|         } | ||||
|  | ||||
|         if(data->bits.urlstringalloc) | ||||
| @@ -713,18 +757,57 @@ CURLcode curl_transfer(CURL *curl) | ||||
|         data->newurl = NULL; /* don't show! */ | ||||
|         data->bits.urlstringalloc = TRUE; /* the URL is allocated */ | ||||
|  | ||||
|         /* Disable both types of POSTs, since doing a second POST when | ||||
|            following isn't what anyone would want! */ | ||||
|         data->bits.http_post = FALSE; | ||||
|         data->bits.http_formpost = FALSE; | ||||
|  | ||||
|         infof(data, "Follows Location: to new URL: '%s'\n", data->url); | ||||
|  | ||||
|         /* | ||||
|          * We get here when the HTTP code is 300-399. We need to perform | ||||
|          * differently based on exactly what return code there was. | ||||
|          * Discussed on the curl mailing list and posted about on the 26th | ||||
|          * of January 2001. | ||||
|          */ | ||||
|         switch(data->progress.httpcode) { | ||||
|         case 300: /* Multiple Choices */ | ||||
|         case 301: /* Moved Permanently */ | ||||
|         case 302: /* Found */ | ||||
|         case 306: /* Not used */ | ||||
|         case 307: /* Temporary Redirect */ | ||||
|         default:  /* for all unknown ones */ | ||||
|           /* These are explicitly mention since I've checked RFC2616 and they | ||||
|            * seem to be OK to POST to. | ||||
|            */ | ||||
|           break; | ||||
|         case 303: /* See Other */ | ||||
|           /* Disable both types of POSTs, since doing a second POST when | ||||
|            * following isn't what anyone would want! */ | ||||
|           data->bits.http_post = FALSE; | ||||
|           data->bits.http_formpost = FALSE; | ||||
|           data->httpreq = HTTPREQ_GET; /* enfore GET request */ | ||||
|           infof(data, "Disables POST\n"); | ||||
|           break; | ||||
|         case 304: /* Not Modified */ | ||||
|           /* 304 means we did a conditional request and it was "Not modified". | ||||
|            * We shouldn't get any Location: header in this response! | ||||
|            */ | ||||
|           break; | ||||
|         case 305: /* Use Proxy */ | ||||
|           /* (quote from RFC2616, section 10.3.6): | ||||
|            * "The requested resource MUST be accessed through the proxy given | ||||
|            * by the Location field. The Location field gives the URI of the | ||||
|            * proxy.  The recipient is expected to repeat this single request | ||||
|            * via the proxy. 305 responses MUST only be generated by origin | ||||
|            * servers." | ||||
|            */ | ||||
|           break; | ||||
|         } | ||||
| #ifdef USE_OLD_DISCONNECT | ||||
|         curl_disconnect(c_connect); | ||||
| #endif | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
| #ifdef USE_OLD_DISCONNECT | ||||
|       curl_disconnect(c_connect); | ||||
| #endif | ||||
|     } | ||||
|     break; /* it only reaches here when this shouldn't loop */ | ||||
|  | ||||
|   | ||||
							
								
								
									
										464
									
								
								lib/urldata.h
									
									
									
									
									
								
							
							
						
						
									
										464
									
								
								lib/urldata.h
									
									
									
									
									
								
							| @@ -82,8 +82,8 @@ | ||||
| /* Download buffer size, keep it fairly big for speed reasons */ | ||||
| #define BUFSIZE (1024*50) | ||||
|  | ||||
| /* Upload buffer size, keep it smallish to get faster progress meter | ||||
|    updates. This should probably become dynamic and adjust to the upload | ||||
| /* Defaul upload buffer size, keep it smallish to get faster progress meter | ||||
|    updates. This is just default, it is dynamic and adjusts to the upload | ||||
|    speed. */ | ||||
| #define UPLOAD_BUFSIZE (1024*2) | ||||
|  | ||||
| @@ -91,10 +91,14 @@ | ||||
|    of need. */ | ||||
| #define HEADERSIZE 256 | ||||
|  | ||||
| /* Just a convenience macro to get the larger value out of two given */ | ||||
| #ifndef MAX | ||||
| #define MAX(x,y) ((x)>(y)?(x):(y)) | ||||
| #endif | ||||
|  | ||||
| /* Type of handle. All publicly returned 'handles' in the curl interface | ||||
|    have a handle first in the struct that describes what kind of handle it | ||||
|    is. Used to detect bad handle usage. */ | ||||
| typedef enum { | ||||
|   STRUCT_NONE, | ||||
|   STRUCT_OPEN, | ||||
| @@ -102,6 +106,8 @@ typedef enum { | ||||
|   STRUCT_LAST | ||||
| } Handle; | ||||
|  | ||||
| /* Connecting to a remote server using the curl interface is moving through | ||||
|    a state machine, this type is used to store the current state */ | ||||
| typedef enum { | ||||
|   CONN_NONE,  /* illegal state */ | ||||
|   CONN_INIT,  /* curl_connect() has been called */ | ||||
| @@ -112,6 +118,7 @@ typedef enum { | ||||
| } ConnState; | ||||
|  | ||||
| #ifdef KRB4 | ||||
| /* Types needed for krb4-ftp connections */ | ||||
| struct krb4buffer { | ||||
|   void *data; | ||||
|   size_t size; | ||||
| @@ -126,6 +133,64 @@ enum protection_level { | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| /* struct for data related to SSL and SSL connections */ | ||||
| struct ssl_connect_data { | ||||
|   bool use;              /* use ssl encrypted communications TRUE/FALSE */ | ||||
| #ifdef USE_SSLEAY | ||||
|   /* these ones requires specific SSL-types */ | ||||
|   SSL_CTX* ctx; | ||||
|   SSL*     handle; | ||||
|   X509*    server_cert; | ||||
| #endif /* USE_SSLEAY */ | ||||
| }; | ||||
|  | ||||
| struct ssl_config_data { | ||||
|   long version;          /* what version the client wants to use */ | ||||
|   long certverifyresult; /* result from the certificate verification */ | ||||
|   long verifypeer;       /* set TRUE if this is desired */ | ||||
|   char *CApath;          /* DOES NOT WORK ON WINDOWS */ | ||||
|   char *CAfile;          /* cerficate to verify peer against */ | ||||
| }; | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * HTTP unique setup | ||||
|  ***************************************************************************/ | ||||
| struct HTTP { | ||||
|   struct FormData *sendit; | ||||
|   int postsize; | ||||
|   char *p_pragma;      /* Pragma: string */ | ||||
|   char *p_accept;      /* Accept: string */ | ||||
|   long readbytecount;  | ||||
|   long writebytecount; | ||||
|  | ||||
|   /* For FORM posting */ | ||||
|   struct Form form; | ||||
|   size_t (*storefread)(char *, size_t , size_t , FILE *); | ||||
|   FILE *in; | ||||
| }; | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * FTP unique setup | ||||
|  ***************************************************************************/ | ||||
| struct FTP { | ||||
|   long *bytecountp; | ||||
|   char *user;    /* user name string */ | ||||
|   char *passwd;  /* password string */ | ||||
|   char *urlpath; /* the originally given path part of the URL */ | ||||
|   char *dir;     /* decoded directory */ | ||||
|   char *file;    /* decoded file */ | ||||
|  | ||||
|   char *entrypath; /* the PWD reply when we logged on */ | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Boolean values that concerns this connection. | ||||
|  */ | ||||
| struct ConnectBits { | ||||
|   bool close; /* if set, we close the connection after this request */ | ||||
|   bool reuse; /* if set, this is a re-used connection */ | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * The connectdata struct contains all fields and variables that should be | ||||
|  * unique for an entire connection. | ||||
| @@ -138,6 +203,9 @@ struct connectdata { | ||||
|   Handle handle; /* struct identifier */ | ||||
|   struct UrlData *data; /* link to the root CURL struct */ | ||||
|  | ||||
|   int connectindex; /* what index in the connects index this particular | ||||
|                        struct has */ | ||||
|  | ||||
|   /**** curl_connect() phase fields */ | ||||
|   ConnState state; /* for state dependent actions */ | ||||
|  | ||||
| @@ -152,20 +220,38 @@ struct connectdata { | ||||
| #define PROT_LDAP    (1<<7) | ||||
| #define PROT_FILE    (1<<8) | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|   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 */ | ||||
|   struct hostent *hp; | ||||
|   struct sockaddr_in serv_addr; | ||||
|   char proto[64]; | ||||
|   char gname[256]; | ||||
|   char *name; | ||||
|   char *path; /* formerly staticly this size: URL_MAX_LENGTH */ | ||||
| #endif | ||||
|   char protostr[64];  /* store the protocol string in this buffer */ | ||||
|   char gname[257]; /* store the hostname in this buffer */ | ||||
|   char *name;      /* host name pointer to fool around with */ | ||||
|   char *path;      /* allocated buffer to store the URL's path part in */ | ||||
|   char *hostname;  /* hostname to connect, as parsed from url */ | ||||
|   long port;       /* which port to use locally */ | ||||
|   unsigned short remote_port; /* what remote port to connect to, | ||||
|                                  not the proxy port! */ | ||||
|   char *ppath; | ||||
|   long bytecount; | ||||
|   struct timeval now; | ||||
|   struct timeval now; /* current time */ | ||||
|   int firstsocket;     /* the main socket to use */ | ||||
|   int secondarysocket; /* for i.e ftp transfers */ | ||||
|  | ||||
|   long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE | ||||
|                           never smaller than UPLOAD_BUFSIZE */ | ||||
|  | ||||
|   long maxdownload; /* in bytes, the maximum amount of data to fetch, 0 | ||||
|                        means unlimited */ | ||||
|    | ||||
|   struct ssl_connect_data ssl; /* this is for ssl-stuff */ | ||||
|  | ||||
|   struct ConnectBits bits;    /* various state-flags for this connection */ | ||||
|  | ||||
|   /* These two functions MUST be set by the curl_connect() function to be | ||||
|      be protocol dependent */ | ||||
|   CURLcode (*curl_do)(struct connectdata *connect); | ||||
| @@ -176,6 +262,11 @@ struct connectdata { | ||||
|    */  | ||||
|   CURLcode (*curl_connect)(struct connectdata *connect); | ||||
|  | ||||
|   /* This function *MAY* be set to a protocol-dependent function that is run | ||||
|    * by the curl_disconnect(), as a step in the disconnection. | ||||
|    */  | ||||
|   CURLcode (*curl_disconnect)(struct connectdata *connect); | ||||
|  | ||||
|   /* This function *MAY* be set to a protocol-dependent function that is run | ||||
|    * in the curl_close() function if protocol-specific cleanups are required. | ||||
|    */  | ||||
| @@ -194,6 +285,18 @@ struct connectdata { | ||||
|                             the same we read from. -1 disables */ | ||||
|   long *writebytecountp; /* return number of bytes written or NULL */ | ||||
|  | ||||
|   /** Dynamicly allocated strings, may need to be freed before this **/ | ||||
|   /** struct is killed.                                             **/ | ||||
|   struct dynamically_allocated_data { | ||||
|     char *proxyuserpwd; /* free later if not NULL! */ | ||||
|     char *uagent; /* free later if not NULL! */ | ||||
|     char *userpwd; /* free later if not NULL! */ | ||||
|     char *rangeline; /* free later if not NULL! */ | ||||
|     char *ref; /* free later if not NULL! */ | ||||
|     char *cookie; /* free later if not NULL! */ | ||||
|     char *host; /* free later if not NULL */ | ||||
|   } allocptr; | ||||
|  | ||||
| #ifdef KRB4 | ||||
|  | ||||
|   enum protection_level command_prot; | ||||
| @@ -207,6 +310,24 @@ struct connectdata { | ||||
|   void *app_data; | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   /*************** Request - specific items ************/ | ||||
|   /* previously this was in the urldata struct */ | ||||
|   union { | ||||
|     struct HTTP *http; | ||||
|     struct HTTP *gopher; /* alias, just for the sake of being more readable */ | ||||
|     struct HTTP *https;  /* alias, just for the sake of being more readable */ | ||||
|     struct FTP *ftp; | ||||
| #if 0 /* no need for special ones for these: */ | ||||
|     struct TELNET *telnet; | ||||
|     struct FILE *file; | ||||
|     struct LDAP *ldap; | ||||
|     struct DICT *dict; | ||||
| #endif | ||||
|     void *generic; | ||||
|   } proto; | ||||
|  | ||||
|  | ||||
| }; | ||||
|  | ||||
| struct Progress { | ||||
| @@ -242,36 +363,25 @@ struct Progress { | ||||
|   int speeder_c; | ||||
| }; | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * HTTP unique setup | ||||
|  ***************************************************************************/ | ||||
| struct HTTP { | ||||
|   struct FormData *sendit; | ||||
|   int postsize; | ||||
|   char *p_pragma; | ||||
|   char *p_accept; | ||||
|   long readbytecount; | ||||
|   long writebytecount; | ||||
|  | ||||
|   /* For FORM posting */ | ||||
|   struct Form form; | ||||
|   size_t (*storefread)(char *, size_t , size_t , FILE *); | ||||
|   FILE *in; | ||||
| }; | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * FTP unique setup | ||||
|  ***************************************************************************/ | ||||
| struct FTP { | ||||
|   long *bytecountp; | ||||
|   char *user; | ||||
|   char *passwd; | ||||
|   char *urlpath; /* the originally given path part of the URL */ | ||||
|   char *dir;     /* decoded directory */ | ||||
|   char *file;    /* decoded file */ | ||||
| }; | ||||
| typedef enum { | ||||
|   HTTPREQ_NONE, /* first in list */ | ||||
|   HTTPREQ_GET, | ||||
|   HTTPREQ_POST, | ||||
|   HTTPREQ_POST_FORM, /* we make a difference internally */ | ||||
|   HTTPREQ_PUT, | ||||
|   HTTPREQ_CUSTOM, | ||||
|   HTTPREQ_LAST /* last in list */ | ||||
| } Curl_HttpReq; | ||||
|  | ||||
| /* This struct is for boolean settings that define how to behave during | ||||
|    this session. */ | ||||
| struct Configbits { | ||||
|   /* these four request types mirror the httpreq field */ | ||||
|   bool http_formpost; | ||||
|   bool http_post; | ||||
|   bool http_put; | ||||
|   bool http_get; | ||||
|  | ||||
|   bool get_filetime; | ||||
|   bool tunnel_thru_httpproxy; | ||||
|   bool ftp_append; | ||||
| @@ -281,10 +391,7 @@ struct Configbits { | ||||
|   bool hide_progress; | ||||
|   bool http_fail_on_error; | ||||
|   bool http_follow_location; | ||||
|   bool http_formpost; | ||||
|   bool http_include_header; | ||||
|   bool http_post; | ||||
|   bool http_put; | ||||
|   bool http_set_referer; | ||||
|   bool http_auto_referer; /* set "correct" referer when following location: */ | ||||
|   bool httpproxy; | ||||
| @@ -299,7 +406,6 @@ struct Configbits { | ||||
|   bool verbose; | ||||
|   bool this_is_a_follow; /* this is a followed Location: request */ | ||||
|   bool krb4; /* kerberos4 connection requested */ | ||||
|  | ||||
|   bool proxystringalloc; /* the http proxy string is malloc()'ed */ | ||||
|   bool rangestringalloc; /* the range string is malloc()'ed */ | ||||
|   bool urlstringalloc;   /* the URL string is malloc()'ed */ | ||||
| @@ -313,21 +419,6 @@ typedef enum { | ||||
|   CURLI_LAST | ||||
| } CurlInterface; | ||||
|  | ||||
| struct ssldata { | ||||
|   bool use;              /* use ssl encrypted communications TRUE/FALSE */ | ||||
|   long version;          /* what version the client wants to use */ | ||||
|   long certverifyresult; /* result from the certificate verification */ | ||||
|   long verifypeer;       /* set TRUE if this is desired */ | ||||
|   char *CApath;          /* DOES NOT WORK ON WINDOWS */ | ||||
|   char *CAfile;          /* cerficate to verify peer against */ | ||||
| #ifdef USE_SSLEAY | ||||
|   /* these ones requires specific SSL-types */ | ||||
|   SSL_CTX* ctx; | ||||
|   SSL*     handle; | ||||
|   X509*    server_cert; | ||||
| #endif /* USE_SSLEAY */ | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * As of April 11, 2000 we're now trying to split up the urldata struct in | ||||
|  * three different parts: | ||||
| @@ -342,8 +433,15 @@ struct ssldata { | ||||
|  * | ||||
|  * (Request) | ||||
|  * 3 - Request-specific. Variables that are of interest for this particular | ||||
|  *     transfer being made right now. | ||||
|  *     transfer being made right now. THIS IS WRONG STRUCT FOR THOSE. | ||||
|  * | ||||
|  * In Febrary 2001, this is being done stricter. The 'connectdata' struct | ||||
|  * MUST have all the connection oriented stuff as we may now have several | ||||
|  * simultaneous connections and connection structs in memory. | ||||
|  * | ||||
|  * From now on, the 'UrlData' must only contain data that is set once to go | ||||
|  * for many (perhaps) independent connections. Values that are generated or | ||||
|  * calculated internally MUST NOT be a part of this struct. | ||||
|  */ | ||||
|  | ||||
| struct UrlData { | ||||
| @@ -355,7 +453,7 @@ struct UrlData { | ||||
|   char *errorbuffer; /* store failure messages in here */ | ||||
|  | ||||
|   /*************** Session - specific items ************/ | ||||
|   char *proxy; /* if proxy, set it here, set CONF_PROXY to use this */ | ||||
|   char *proxy; /* if proxy, set it here */ | ||||
|   char *proxyuserpwd;  /* Proxy <user:password>, if used */ | ||||
|   long proxyport; /* If non-zero, use this port number by default. If the | ||||
|                      proxy string features a ":[port]" that one will override | ||||
| @@ -365,33 +463,14 @@ struct UrlData { | ||||
|   long header_size;  /* size of read header(s) in bytes */ | ||||
|   long request_size; /* the amount of bytes sent in the request(s) */ | ||||
|  | ||||
|   /*************** Request - specific items ************/ | ||||
|  | ||||
|   union { | ||||
|     struct HTTP *http; | ||||
|     struct HTTP *gopher; /* alias, just for the sake of being more readable */ | ||||
|     struct HTTP *https;  /* alias, just for the sake of being more readable */ | ||||
|     struct FTP *ftp; | ||||
| #if 0 /* no need for special ones for these: */ | ||||
|     struct TELNET *telnet; | ||||
|     struct FILE *file; | ||||
|     struct LDAP *ldap; | ||||
|     struct DICT *dict; | ||||
| #endif | ||||
|     void *generic; | ||||
|   } proto; | ||||
|  | ||||
|   FILE *out;    /* the fetched file goes here */ | ||||
|   FILE *in;     /* the uploaded file is read from here */ | ||||
|   FILE *writeheader; /* write the header to this is non-NULL */ | ||||
|   char *url;   /* what to get */ | ||||
|   char *freethis; /* if non-NULL, an allocated string for the URL */ | ||||
|   char *hostname; /* hostname to connect, as parsed from url */ | ||||
|   long port; /* which port to use (if non-protocol bind) set | ||||
|                 CONF_PORT to use this */ | ||||
|   unsigned short remote_port; /* what remote port to connect to, not the proxy | ||||
| 				 port! */ | ||||
|   long use_port;  /* which port to use (when not using default) */ | ||||
|   struct Configbits bits; /* new-style (v7) flag data */ | ||||
|   struct ssl_config_data ssl; /* this is for ssl-stuff */ | ||||
|  | ||||
|   char *userpwd;  /* <user:password>, if used */ | ||||
|   char *range; /* range, if used. See README for detailed specification on | ||||
| @@ -433,13 +512,6 @@ struct UrlData { | ||||
|   long timeout; /* in seconds, 0 means no timeout */ | ||||
|   long infilesize; /* size of file to upload, -1 means unknown */ | ||||
|  | ||||
|   long maxdownload; /* in bytes, the maximum amount of data to fetch, 0 | ||||
|                        means unlimited */ | ||||
|    | ||||
|   /* fields only set and used within _urlget() */ | ||||
|   int firstsocket;     /* the main socket to use */ | ||||
|   int secondarysocket; /* for i.e ftp transfers */ | ||||
|  | ||||
|   char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */ | ||||
|  | ||||
|   double current_speed;  /* the ProgressShow() funcion sets this */ | ||||
| @@ -462,27 +534,24 @@ struct UrlData { | ||||
|  | ||||
|   struct CookieInfo *cookies; | ||||
|  | ||||
|   struct ssldata ssl; /* this is for ssl-stuff */ | ||||
|  | ||||
|   long crlf; | ||||
|   struct curl_slist *quote;     /* before the transfer */ | ||||
|   struct curl_slist *postquote; /* after the transfer */ | ||||
|  | ||||
|   TimeCond timecondition; | ||||
|   time_t timevalue; | ||||
|   /* Telnet negotiation options */ | ||||
|   struct curl_slist *telnet_options; /* linked list of telnet options */ | ||||
|  | ||||
|   TimeCond timecondition; /* kind of comparison */ | ||||
|   time_t timevalue;       /* what time to compare with */ | ||||
|  | ||||
|   Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ | ||||
|  | ||||
|   char *customrequest; /* http/ftp request to use */ | ||||
|  | ||||
|   char *headerbuff; /* allocated buffer to store headers in */ | ||||
|   int headersize;   /* size of the allocation */ | ||||
|  | ||||
| #if 0 | ||||
|   /* this was removed in libcurl 7.4 */ | ||||
|   char *writeinfo;  /* if non-NULL describes what to output on a successful | ||||
|                        completion */ | ||||
| #endif | ||||
|  | ||||
|   struct Progress progress; | ||||
|   struct Progress progress; /* for all the progress meter data */ | ||||
|  | ||||
| #define MAX_CURL_USER_LENGTH 128 | ||||
| #define MAX_CURL_PASSWORD_LENGTH 128 | ||||
| @@ -492,30 +561,215 @@ struct UrlData { | ||||
|                     * host (which location-following otherwise could lead to) | ||||
|                     */ | ||||
|  | ||||
|   /* buffers to store authentication data in */ | ||||
|   char user[MAX_CURL_USER_LENGTH]; | ||||
|   char passwd[MAX_CURL_PASSWORD_LENGTH]; | ||||
|   char proxyuser[MAX_CURL_USER_LENGTH]; | ||||
|   char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; | ||||
|  | ||||
|   /**** Dynamicly allocated strings, may need to be freed on return ****/ | ||||
|   char *ptr_proxyuserpwd; /* free later if not NULL! */ | ||||
|   char *ptr_uagent; /* free later if not NULL! */ | ||||
|   char *ptr_userpwd; /* free later if not NULL! */ | ||||
|   char *ptr_rangeline; /* free later if not NULL! */ | ||||
|   char *ptr_ref; /* free later if not NULL! */ | ||||
|   char *ptr_cookie; /* free later if not NULL! */ | ||||
|   char *ptr_host; /* free later if not NULL */ | ||||
|  | ||||
|   char *krb4_level; | ||||
|   char *krb4_level; /* what security level */ | ||||
| #ifdef KRB4 | ||||
|   FILE *cmdchannel; | ||||
| #endif | ||||
|  | ||||
|   struct timeval keeps_speed; /* this should be request-specific */ | ||||
|  | ||||
|   /* 'connects' will be an allocated array with pointers. If the pointer is | ||||
|      set, it holds an allocated connection. */ | ||||
|   struct connectdata **connects; | ||||
|   size_t numconnects; /* size of the 'connects' array */ | ||||
|   curl_closepolicy closepolicy; | ||||
|  | ||||
| }; | ||||
|  | ||||
| #define LIBCURL_NAME "libcurl" | ||||
| #define LIBCURL_ID LIBCURL_NAME " " LIBCURL_VERSION " " SSL_ID | ||||
|  | ||||
| /* | ||||
|  * Here follows function prototypes from what we used to plan to call | ||||
|  * the "low level" interface. It is no longer prioritized and it is not likely | ||||
|  * to ever be supported to external users. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * NAME	curl_init() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Inits libcurl globally. This must be used before any libcurl calls can | ||||
|  * be used. This may install global plug-ins or whatever. (This does not | ||||
|  * do winsock inits in Windows.) | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * curl_init(); | ||||
|  * | ||||
|  */ | ||||
| CURLcode curl_init(void); | ||||
|  | ||||
| /* | ||||
|  * NAME	curl_init() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Frees libcurl globally. This must be used after all libcurl calls have | ||||
|  * been used. This may remove global plug-ins or whatever. (This does not | ||||
|  * do winsock cleanups in Windows.) | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * curl_free(curl); | ||||
|  * | ||||
|  */ | ||||
| void curl_free(void); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_open() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Opens a general curl session. It does not try to connect or do anything | ||||
|  * on the network because of this call. The specified URL is only required | ||||
|  * to enable curl to figure out what protocol to "activate". | ||||
|  * | ||||
|  * A session should be looked upon as a series of requests to a single host.  A | ||||
|  * session interacts with one host only, using one single protocol. | ||||
|  * | ||||
|  * The URL is not required. If set to "" or NULL, it can still be set later | ||||
|  * using the curl_setopt() function. If the curl_connect() function is called | ||||
|  * without the URL being known, it will return error. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLcode result; | ||||
|  * CURL *curl; | ||||
|  * result = curl_open(&curl, "http://curl.haxx.nu/libcurl/"); | ||||
|  * if(result != CURL_OK) { | ||||
|  *   return result; | ||||
|  * } | ||||
|  * */ | ||||
| CURLcode curl_open(CURL **curl, char *url); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_setopt() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Sets a particular option to the specified value. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURL curl; | ||||
|  * curl_setopt(curl, CURL_HTTP_FOLLOW_LOCATION, TRUE); | ||||
|  */ | ||||
| CURLcode curl_setopt(CURL *handle, CURLoption option, ...); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_close() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Closes a session previously opened with curl_open() | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURL *curl; | ||||
|  * CURLcode result; | ||||
|  * | ||||
|  * result = curl_close(curl); | ||||
|  */ | ||||
| CURLcode curl_close(CURL *curl); /* the opposite of curl_open() */ | ||||
|  | ||||
| CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, | ||||
|                    ssize_t *n); | ||||
| CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, | ||||
|                     size_t *n); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_connect() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Connects to the peer server and performs the initial setup. This function | ||||
|  * writes a connect handle to its second argument that is a unique handle for | ||||
|  * this connect. This allows multiple connects from the same handle returned | ||||
|  * by curl_open(). | ||||
|  * | ||||
|  * By setting 'allow_port' to FALSE, the data->use_port will *NOT* be | ||||
|  * respected. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLCode result; | ||||
|  * CURL curl; | ||||
|  * CURLconnect connect; | ||||
|  * result = curl_connect(curl, &connect); */ | ||||
|  | ||||
| CURLcode curl_connect(CURL *curl, | ||||
|                       CURLconnect **in_connect, | ||||
|                       bool allow_port); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_do() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * (Note: May 3rd 2000: this function does not currently allow you to | ||||
|  * specify a document, it will use the one set previously) | ||||
|  * | ||||
|  * This function asks for the particular document, file or resource that | ||||
|  * resides on the server we have connected to. You may specify a full URL, | ||||
|  * just an absolute path or even a relative path. That means, if you're just | ||||
|  * getting one file from the remote site, you can use the same URL as input | ||||
|  * for both curl_open() as well as for this function. | ||||
|  * | ||||
|  * In the even there is a host name, port number, user name or password parts | ||||
|  * in the URL, you can use the 'flags' argument to ignore them completely, or | ||||
|  * at your choice, make the function fail if you're trying to get a URL from | ||||
|  * different host than you connected to with curl_connect(). | ||||
|  * | ||||
|  * You can only get one document at a time using the same connection. When one | ||||
|  * document has been received you can although request again. | ||||
|  * | ||||
|  * When the transfer is done, curl_done() MUST be called. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLCode result; | ||||
|  * char *url; | ||||
|  * CURLconnect *connect; | ||||
|  * result = curl_do(connect, url, CURL_DO_NONE); */ | ||||
| CURLcode curl_do(CURLconnect *in_conn); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_done() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * When the transfer following a curl_do() call is done, this function should | ||||
|  * get called. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLCode result; | ||||
|  * char *url; | ||||
|  * CURLconnect *connect; | ||||
|  * result = curl_done(connect); */ | ||||
| CURLcode curl_done(CURLconnect *connect); | ||||
|  | ||||
| /* | ||||
|  * NAME curl_disconnect() | ||||
|  * | ||||
|  * DESCRIPTION | ||||
|  * | ||||
|  * Disconnects from the peer server and performs connection cleanup. | ||||
|  * | ||||
|  * EXAMPLE | ||||
|  * | ||||
|  * CURLcode result; | ||||
|  * CURLconnect *connect; | ||||
|  * result = curl_disconnect(connect); */ | ||||
| CURLcode curl_disconnect(CURLconnect *connect); | ||||
|  | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -61,8 +61,18 @@ char *curl_version(void) | ||||
|   ptr=strchr(ptr, '\0'); | ||||
| #endif | ||||
|  | ||||
| #if defined(KRB4) || defined(ENABLE_IPV6) | ||||
|   strcat(ptr, " ("); | ||||
|   ptr+=2; | ||||
| #ifdef KRB4 | ||||
|   sprintf(ptr, " (krb4 enabled)"); | ||||
|   sprintf(ptr, "krb4 "); | ||||
|   ptr += strlen(ptr); | ||||
| #endif | ||||
| #ifdef ENABLE_IPV6 | ||||
|   sprintf(ptr, "ipv6 "); | ||||
|   ptr += strlen(ptr); | ||||
| #endif | ||||
|   sprintf(ptr, "enabled)"); | ||||
|   ptr += strlen(ptr); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -26,13 +26,17 @@ while(<STDIN>) { | ||||
|  | ||||
|         if($function =~ /free\(0x([0-9a-f]*)/) { | ||||
|             $addr = $1; | ||||
|             if($sizeataddr{$addr} <= 0) { | ||||
|             if($sizeataddr{$addr} == 0) { | ||||
|                 print "FREE ERROR: No memory allocated: $line\n"; | ||||
|             } | ||||
|             elsif(-1 == $sizeataddr{$addr}) { | ||||
|                 print "FREE ERROR: Memory freed twice: $line\n"; | ||||
|                 print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n"; | ||||
|             } | ||||
|             else { | ||||
|                 $totalmem -= $sizeataddr{$addr}; | ||||
|                 $sizeataddr{$addr}=0; | ||||
|                 $getmem{$addr}=""; # forget after a good free() | ||||
|                 $sizeataddr{$addr}=-1; # set -1 to mark as freed | ||||
|                 $getmem{$addr}="$source:$linenum"; | ||||
|             } | ||||
|         } | ||||
|         elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) { | ||||
| @@ -141,7 +145,7 @@ if($totalmem) { | ||||
|     for(keys %sizeataddr) { | ||||
|         $addr = $_; | ||||
|         $size = $sizeataddr{$addr}; | ||||
|         if($size) { | ||||
|         if($size > 0) { | ||||
|             print "At $addr, there's $size bytes.\n"; | ||||
|             print " allocated by ".$getmem{$addr}."\n"; | ||||
|         } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ LINKR = link.exe /incremental:no /libpath:"../lib" | ||||
|  | ||||
| ## Debug | ||||
| CCD = cl.exe /MDd /Gm /ZI /Od /D "_DEBUG" /GZ | ||||
| LINKD = link.exe /incremental:yes /debug | ||||
| LINKD = link.exe /incremental:yes /debug /libpath:"../lib" | ||||
|  | ||||
| CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | ||||
| LFLAGS = /nologo /out:$(PROGRAM_NAME) /subsystem:console /machine:I386 | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -48,7 +48,7 @@ | ||||
| /* This is now designed to have its own local setup.h */ | ||||
| #include "setup.h" | ||||
|  | ||||
| #ifdef WIN32 | ||||
| #if defined(WIN32)&&!defined(__CYGWIN32__) | ||||
| #include <winsock.h> | ||||
| #endif | ||||
|  | ||||
| @@ -102,14 +102,13 @@ typedef enum { | ||||
| #define CONF_NOBODY   (1<<11) /* use HEAD to get http document */ | ||||
| #define CONF_FAILONERROR (1<<12) /* no output on http error codes >= 300 */ | ||||
| #define CONF_UPLOAD   (1<<14) /* this is an upload */ | ||||
| #define CONF_POST     (1<<15) /* HTTP POST method */ | ||||
| #define CONF_FTPLISTONLY (1<<16) /* Use NLST when listing ftp dir */ | ||||
| #define CONF_FTPAPPEND (1<<20) /* Append instead of overwrite on upload! */ | ||||
| #define CONF_NETRC    (1<<22)  /* read user+password from .netrc */ | ||||
| #define CONF_FOLLOWLOCATION (1<<23) /* use Location: Luke! */ | ||||
| #define CONF_GETTEXT  (1<<24) /* use ASCII/text for transfer */ | ||||
| #define CONF_HTTPPOST (1<<25) /* multipart/form-data HTTP POST */ | ||||
| #define CONF_PUT      (1<<27) /* PUT the input file */ | ||||
|  | ||||
| #define CONF_MUTE     (1<<28) /* force NOPROGRESS */ | ||||
|  | ||||
| #ifndef HAVE_STRDUP | ||||
| @@ -244,7 +243,6 @@ static void help(void) | ||||
|        " -A/--user-agent <string> User-Agent to send to server (H)\n" | ||||
|        " -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n" | ||||
|        " -B/--use-ascii     Use ASCII/text transfer\n" | ||||
|        " -c/--continue      Resume a previous transfer where we left it\n" | ||||
|        " -C/--continue-at <offset> Specify absolute resume offset\n" | ||||
|        " -d/--data <data>   HTTP POST data (H)\n" | ||||
|        "    --data-ascii <data>   HTTP POST ASCII data (H)\n" | ||||
| @@ -278,7 +276,7 @@ static void help(void) | ||||
|        " -r/--range <range> Retrieve a byte range from a HTTP/1.1 or FTP server\n" | ||||
|        " -s/--silent        Silent mode. Don't output anything\n" | ||||
|        " -S/--show-error    Show error. With -s, make curl show errors when they occur\n" | ||||
|        " -t/--upload        Transfer/upload stdin to remote site\n" | ||||
|        " -t/--telnet-option <OPT=val> Set telnet option\n" | ||||
|        " -T/--upload-file <file> Transfer/upload <file> to remote site\n" | ||||
|        "    --url <URL>     Another way to specify URL to work with\n" | ||||
|        " -u/--user <user[:password]> Specify user and password to use\n" | ||||
| @@ -366,6 +364,8 @@ struct Configurable { | ||||
|   struct HttpPost *httppost; | ||||
|   struct HttpPost *last_post; | ||||
|  | ||||
|   struct curl_slist *telnet_options; | ||||
|          | ||||
|   HttpReq httpreq; | ||||
| }; | ||||
|  | ||||
| @@ -565,7 +565,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ | ||||
|     {"r", "range",       TRUE}, | ||||
|     {"s", "silent",      FALSE}, | ||||
|     {"S", "show-error",  FALSE}, | ||||
|     {"t", "upload",      FALSE}, | ||||
|     {"t", "telnet-options", TRUE}, | ||||
|     {"T", "upload-file", TRUE}, | ||||
|     {"u", "user",        TRUE}, | ||||
|     {"U", "proxy-user",  TRUE}, | ||||
| @@ -785,8 +785,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ | ||||
|         else | ||||
|           config->postfields=postdata; | ||||
|       } | ||||
|       if(config->postfields) | ||||
|         config->conf |= CONF_POST; | ||||
|  | ||||
|       if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq)) | ||||
|         return PARAM_BAD_USE; | ||||
|       break; | ||||
| @@ -959,9 +958,8 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ | ||||
|       config->showerror ^= TRUE; /* toggle on if used with -s */ | ||||
|       break; | ||||
|     case 't': | ||||
|       /* we are uploading */ | ||||
|       config->conf ^= CONF_UPLOAD; | ||||
|       fprintf(stderr, "-t is a deprecated switch, use '-T -' instead!\n"); | ||||
|       /* Telnet options */ | ||||
|       config->telnet_options = curl_slist_append(config->telnet_options, nextarg); | ||||
|       break; | ||||
|     case 'T': | ||||
|       /* we are uploading */ | ||||
| @@ -1579,7 +1577,9 @@ operate(struct Configurable *config, int argc, char *argv[]) | ||||
|       /* multiple files extracted to stdout, insert separators! */ | ||||
|       separator = 1; | ||||
|     } | ||||
|     for (i = 0; (url = urls?next_url(urls):(i?NULL:url)); ++i) { | ||||
|     for(i = 0; | ||||
|         (url = urls?next_url(urls):(i?NULL:strdup(url))); | ||||
|         i++) { | ||||
|       char *outfile; | ||||
|       outfile = outfiles?strdup(outfiles):NULL; | ||||
|   | ||||
| @@ -1713,7 +1713,7 @@ operate(struct Configurable *config, int argc, char *argv[]) | ||||
|       if(!config->errors) | ||||
|         config->errors = stderr; | ||||
|  | ||||
| #ifdef WIN32 | ||||
| #if defined(WIN32) && !defined(__CYGWIN32__) | ||||
|       if(!outfile && !(config->conf & CONF_GETTEXT)) { | ||||
|         /* We get the output to stdout and we have not got the ASCII/text flag, | ||||
|            then set stdout to be binary */ | ||||
| @@ -1741,7 +1741,6 @@ operate(struct Configurable *config, int argc, char *argv[]) | ||||
|         curl_easy_setopt(curl, CURLOPT_FAILONERROR, | ||||
|                          config->conf&CONF_FAILONERROR); | ||||
|         curl_easy_setopt(curl, CURLOPT_UPLOAD, config->conf&CONF_UPLOAD); | ||||
|         curl_easy_setopt(curl, CURLOPT_POST, config->conf&CONF_POST); | ||||
|         curl_easy_setopt(curl, CURLOPT_FTPLISTONLY, | ||||
|                          config->conf&CONF_FTPLISTONLY); | ||||
|         curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND); | ||||
| @@ -1749,7 +1748,6 @@ operate(struct Configurable *config, int argc, char *argv[]) | ||||
|         curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, | ||||
|                          config->conf&CONF_FOLLOWLOCATION); | ||||
|         curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT); | ||||
|         curl_easy_setopt(curl, CURLOPT_PUT, config->conf&CONF_PUT); | ||||
|         curl_easy_setopt(curl, CURLOPT_MUTE, config->conf&CONF_MUTE); | ||||
|         curl_easy_setopt(curl, CURLOPT_USERPWD, config->userpwd); | ||||
|         curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd); | ||||
| @@ -1820,6 +1818,9 @@ operate(struct Configurable *config, int argc, char *argv[]) | ||||
|           curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar); | ||||
|         } | ||||
|          | ||||
|         /* new in libcurl 7.6.2: */ | ||||
|         curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, config->telnet_options); | ||||
|          | ||||
|         res = curl_easy_perform(curl); | ||||
|          | ||||
|         if(config->writeout) { | ||||
|   | ||||
							
								
								
									
										161
									
								
								src/urlglob.c
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								src/urlglob.c
									
									
									
									
									
								
							| @@ -32,9 +32,23 @@ | ||||
| #include "../lib/memdebug.h" | ||||
| #endif | ||||
|  | ||||
| int glob_word(URLGlob *, char*, int); | ||||
| typedef enum { | ||||
|   GLOB_OK, | ||||
|   GLOB_ERROR | ||||
| } GlobCode; | ||||
|  | ||||
| int glob_set(URLGlob *glob, char *pattern, int pos) | ||||
| /* | ||||
|  * glob_word() | ||||
|  * | ||||
|  * Input a full globbed string, set the forth argument to the amount of | ||||
|  * strings we get out of this. Return GlobCode. | ||||
|  */ | ||||
| GlobCode glob_word(URLGlob *, /* object anchor */ | ||||
|                    char *,    /* globbed string */ | ||||
|                    int,       /* position */ | ||||
|                    int *);    /* returned number of strings */ | ||||
|  | ||||
| GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount) | ||||
| { | ||||
|   /* processes a set expression with the point behind the opening '{' | ||||
|      ','-separated elements are collected until the next closing '}' | ||||
| @@ -53,12 +67,14 @@ int glob_set(URLGlob *glob, char *pattern, int pos) | ||||
|   while (1) { | ||||
|     switch (*pattern) { | ||||
|     case '\0':			/* URL ended while set was still open */ | ||||
|       printf("error: unmatched brace at pos %d\n", pos); | ||||
|       exit (CURLE_URL_MALFORMAT); | ||||
|       /*printf("error: unmatched brace at pos %d\n", pos);*/ | ||||
|       return GLOB_ERROR; | ||||
|  | ||||
|     case '{': | ||||
|     case '[':			/* no nested expressions at this time */ | ||||
|       printf("error: nested braces not supported %d\n", pos); | ||||
|       exit (CURLE_URL_MALFORMAT); | ||||
|       /*printf("error: nested braces not supported %d\n", pos);*/ | ||||
|       return GLOB_ERROR; | ||||
|  | ||||
|     case ',': | ||||
|     case '}':				/* set element completed */ | ||||
|       *buf = '\0'; | ||||
| @@ -66,40 +82,51 @@ int glob_set(URLGlob *glob, char *pattern, int pos) | ||||
|         realloc(pat->content.Set.elements, | ||||
|                 (pat->content.Set.size + 1) * sizeof(char*)); | ||||
|       if (!pat->content.Set.elements) { | ||||
| 	printf("out of memory in set pattern\n"); | ||||
| 	exit(CURLE_OUT_OF_MEMORY); | ||||
| 	/*printf("out of memory in set pattern\n");*/ | ||||
|         return GLOB_ERROR; | ||||
|       } | ||||
|       pat->content.Set.elements[pat->content.Set.size] = | ||||
|         strdup(glob->glob_buffer); | ||||
|       ++pat->content.Set.size; | ||||
|  | ||||
|       if (*pattern == '}')		/* entire set pattern completed */ | ||||
|       if (*pattern == '}') { | ||||
|         /* entire set pattern completed */ | ||||
|         int wordamount; | ||||
|  | ||||
| 	/* always check for a literal (may be "") between patterns */ | ||||
| 	return pat->content.Set.size * glob_word(glob, ++pattern, ++pos); | ||||
|         if(GLOB_ERROR == glob_word(glob, ++pattern, ++pos, &wordamount)) | ||||
|           wordamount=1; | ||||
| 	*amount = pat->content.Set.size * wordamount; | ||||
|  | ||||
|         return GLOB_OK; | ||||
|       } | ||||
|  | ||||
|       buf = glob->glob_buffer; | ||||
|       ++pattern; | ||||
|       ++pos; | ||||
|       break; | ||||
|  | ||||
|     case ']':				/* illegal closing bracket */ | ||||
|       printf("error: illegal pattern at pos %d\n", pos); | ||||
|       exit (CURLE_URL_MALFORMAT); | ||||
|       /*printf("error: illegal pattern at pos %d\n", pos);*/ | ||||
|       return GLOB_ERROR; | ||||
|  | ||||
|     case '\\':				/* escaped character, skip '\' */ | ||||
|       if (*(buf+1) == '\0') {		/* but no escaping of '\0'! */ | ||||
| 	printf("error: illegal pattern at pos %d\n", pos); | ||||
| 	exit (CURLE_URL_MALFORMAT); | ||||
| 	/*printf("error: illegal pattern at pos %d\n", pos); */ | ||||
| 	return GLOB_ERROR; | ||||
|       } | ||||
|       ++pattern; | ||||
|       ++pos;				/* intentional fallthrough */ | ||||
|  | ||||
|     default: | ||||
|       *buf++ = *pattern++;		/* copy character to set element */ | ||||
|       ++pos; | ||||
|     } | ||||
|   } | ||||
|   exit (CURLE_FAILED_INIT); | ||||
|   return GLOB_ERROR; | ||||
| } | ||||
|  | ||||
| int glob_range(URLGlob *glob, char *pattern, int pos) | ||||
| GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount) | ||||
| { | ||||
|   /* processes a range expression with the point behind the opening '[' | ||||
|      - char range: e.g. "a-z]", "B-Q]" | ||||
| @@ -109,6 +136,7 @@ int glob_range(URLGlob *glob, char *pattern, int pos) | ||||
|   */ | ||||
|   URLPattern *pat; | ||||
|   char *c; | ||||
|   int wordamount=1; | ||||
|    | ||||
|   pat = (URLPattern*)&glob->pattern[glob->size / 2]; | ||||
|   /* patterns 0,1,2,... correspond to size=1,3,5,... */ | ||||
| @@ -116,44 +144,71 @@ int glob_range(URLGlob *glob, char *pattern, int pos) | ||||
|  | ||||
|   if (isalpha((int)*pattern)) {		/* character range detected */ | ||||
|     pat->type = UPTCharRange; | ||||
|     if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c, &pat->content.CharRange.max_c) != 2 || | ||||
|     if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c, | ||||
|                &pat->content.CharRange.max_c) != 2 || | ||||
| 	pat->content.CharRange.min_c >= pat->content.CharRange.max_c || | ||||
| 	pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') { | ||||
|       /* the pattern is not well-formed */  | ||||
|       printf("error: illegal pattern or range specification after pos %d\n", pos); | ||||
|       exit (CURLE_URL_MALFORMAT); | ||||
| #if 0 | ||||
|       printf("error: illegal pattern or range specification after pos %d\n", | ||||
|              pos); | ||||
| #endif | ||||
|       return GLOB_ERROR; | ||||
|     } | ||||
|     pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; | ||||
|     /* always check for a literal (may be "") between patterns */ | ||||
|     return (pat->content.CharRange.max_c - pat->content.CharRange.min_c + 1) * | ||||
|       glob_word(glob, pattern + 4, pos + 4); | ||||
|  | ||||
|     if(GLOB_ERROR == glob_word(glob, pattern + 4, pos + 4, &wordamount)) | ||||
|       wordamount=1; | ||||
|  | ||||
|     *amount = (pat->content.CharRange.max_c - | ||||
|                pat->content.CharRange.min_c + 1) * | ||||
|       wordamount; | ||||
|  | ||||
|     return GLOB_OK; | ||||
|   } | ||||
|  | ||||
|   if (isdigit((int)*pattern)) { /* numeric range detected */ | ||||
|  | ||||
|     pat->type = UPTNumRange; | ||||
|     pat->content.NumRange.padlength = 0; | ||||
|     if (sscanf(pattern, "%d-%d]", &pat->content.NumRange.min_n, &pat->content.NumRange.max_n) != 2 || | ||||
|     if (sscanf(pattern, "%d-%d]", | ||||
|                &pat->content.NumRange.min_n, | ||||
|                &pat->content.NumRange.max_n) != 2 || | ||||
| 	pat->content.NumRange.min_n >= pat->content.NumRange.max_n) { | ||||
|       /* the pattern is not well-formed */  | ||||
|       printf("error: illegal pattern or range specification after pos %d\n", pos); | ||||
|       exit (CURLE_URL_MALFORMAT); | ||||
| #if 0 | ||||
|       printf("error: illegal pattern or range specification after pos %d\n", | ||||
|              pos); | ||||
| #endif | ||||
|       return GLOB_ERROR; | ||||
|     } | ||||
|     if (*pattern == '0') {		/* leading zero specified */ | ||||
|       c = pattern;   | ||||
|       while (isdigit((int)*c++)) | ||||
| 	++pat->content.NumRange.padlength;	/* padding length is set for all instances | ||||
| 						   of this pattern */ | ||||
| 	++pat->content.NumRange.padlength; /* padding length is set for all | ||||
|                                               instances of this pattern */ | ||||
|     } | ||||
|     pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; | ||||
|     c = (char*)(strchr(pattern, ']') + 1);	/* continue after next ']' */ | ||||
|  | ||||
|     /* always check for a literal (may be "") between patterns */ | ||||
|     return (pat->content.NumRange.max_n - pat->content.NumRange.min_n + 1) * | ||||
|       glob_word(glob, c, pos + (c - pattern)); | ||||
|  | ||||
|     if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount)) | ||||
|       wordamount = 1; | ||||
|      | ||||
|     *amount = (pat->content.NumRange.max_n -  | ||||
|                pat->content.NumRange.min_n + 1) * | ||||
|       wordamount; | ||||
|  | ||||
|     return GLOB_OK; | ||||
|   } | ||||
|   printf("error: illegal character in range specification at pos %d\n", pos); | ||||
|   exit (CURLE_URL_MALFORMAT); | ||||
|   /*printf("error: illegal character in range specification at pos %d\n", | ||||
|     pos);*/ | ||||
|   return GLOB_ERROR; | ||||
| } | ||||
|  | ||||
| int glob_word(URLGlob *glob, char *pattern, int pos) | ||||
| GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount) | ||||
| { | ||||
|   /* processes a literal string component of a URL | ||||
|      special characters '{' and '[' branch to set/range processing functions | ||||
| @@ -161,17 +216,17 @@ int glob_word(URLGlob *glob, char *pattern, int pos) | ||||
|   char* buf = glob->glob_buffer; | ||||
|   int litindex; | ||||
|  | ||||
|   *amount = 1; /* default is one single string */ | ||||
|  | ||||
|   while (*pattern != '\0' && *pattern != '{' && *pattern != '[') { | ||||
|     if (*pattern == '}' || *pattern == ']') { | ||||
|       printf("illegal character at position %d\n", pos); | ||||
|       exit (CURLE_URL_MALFORMAT); | ||||
|       return GLOB_ERROR; | ||||
|     } | ||||
|     if (*pattern == '\\') {		/* escape character, skip '\' */ | ||||
|       ++pattern; | ||||
|       ++pos; | ||||
|       if (*pattern == '\0') {		/* but no escaping of '\0'! */ | ||||
| 	printf("illegal character at position %d\n", pos); | ||||
| 	exit (CURLE_URL_MALFORMAT); | ||||
| 	return GLOB_ERROR; | ||||
|       } | ||||
|     } | ||||
|     *buf++ = *pattern++;		/* copy character to literal */ | ||||
| @@ -182,16 +237,21 @@ int glob_word(URLGlob *glob, char *pattern, int pos) | ||||
|   /* literals 0,1,2,... correspond to size=0,2,4,... */ | ||||
|   glob->literal[litindex] = strdup(glob->glob_buffer); | ||||
|   ++glob->size; | ||||
|   if (*pattern == '\0') | ||||
|     return 1;				/* singular URL processed  */ | ||||
|   if (*pattern == '{') { | ||||
|     return glob_set(glob, ++pattern, ++pos);	/* process set pattern */ | ||||
|  | ||||
|   switch (*pattern) { | ||||
|   case '\0': | ||||
|     return GLOB_OK;			/* singular URL processed  */ | ||||
|  | ||||
|   case '{': | ||||
|     /* process set pattern */ | ||||
|     return glob_set(glob, ++pattern, ++pos, amount); | ||||
|  | ||||
|   case '[': | ||||
|     /* process range pattern */ | ||||
|     return glob_range(glob, ++pattern, ++pos, amount); | ||||
|   } | ||||
|   if (*pattern == '[') { | ||||
|     return glob_range(glob, ++pattern, ++pos);/* process range pattern */ | ||||
|   } | ||||
|   printf("internal error\n"); | ||||
|   exit (CURLE_FAILED_INIT); | ||||
|  | ||||
|   return GLOB_ERROR; /* something got wrong */ | ||||
| } | ||||
|  | ||||
| int glob_url(URLGlob** glob, char* url, int *urlnum) | ||||
| @@ -201,7 +261,9 @@ int glob_url(URLGlob** glob, char* url, int *urlnum) | ||||
|    * as the specified URL! | ||||
|    */ | ||||
|   URLGlob *glob_expand; | ||||
|   int amount; | ||||
|   char *glob_buffer=(char *)malloc(strlen(url)+1); | ||||
|  | ||||
|   if(NULL == glob_buffer) | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
| @@ -214,7 +276,16 @@ int glob_url(URLGlob** glob, char* url, int *urlnum) | ||||
|   glob_expand->urllen = strlen(url); | ||||
|   glob_expand->glob_buffer = glob_buffer; | ||||
|   glob_expand->beenhere=0; | ||||
|   *urlnum = glob_word(glob_expand, url, 1); | ||||
|   if(GLOB_OK == glob_word(glob_expand, url, 1, &amount)) | ||||
|     *urlnum = amount; | ||||
|   else { | ||||
|     /* it failed, we cleanup */ | ||||
|     free(glob_buffer); | ||||
|     free(glob_expand); | ||||
|     glob_expand = NULL; | ||||
|     *urlnum = 1; | ||||
|   } | ||||
|  | ||||
|   *glob = glob_expand; | ||||
|   return CURLE_OK; | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| #define CURL_NAME "curl" | ||||
| #define CURL_VERSION "7.6-pre3" | ||||
| #define CURL_VERSION "7.7-alpha2" | ||||
| #define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") " | ||||
|   | ||||
| @@ -53,4 +53,13 @@ command8.txt      name14.txt        prot5.txt \ | ||||
| command9.txt      name15.txt        prot6.txt \ | ||||
| error111.txt      name16.txt        prot7.txt \ | ||||
| command26.txt  prot26.txt     command27.txt  prot27.txt \ | ||||
| name26.txt     reply26.txt    name27.txt     stdout27.txt  | ||||
| name26.txt     reply26.txt    name27.txt     stdout27.txt \ | ||||
| command28.txt  name28.txt     prot28.txt     reply28.txt \ | ||||
| command120.txt  name120.txt     prot120.txt     reply120.txt \ | ||||
| command121.txt  name121.txt     prot121.txt     reply121.txt \ | ||||
| command29.txt  error30.txt  name30.txt  prot30.txt   reply30.txt \ | ||||
| command30.txt  name29.txt   prot29.txt  reply29.txt \ | ||||
| command31.txt  name32.txt  reply31.txt      reply32.txt \ | ||||
| command32.txt  prot31.txt  reply310001.txt  reply320001.txt \ | ||||
| name31.txt     prot32.txt  reply310002.txt  reply320002.txt \ | ||||
| command33.txt  extra33.txt    name33.txt     prot33.txt     reply33.txt | ||||
|   | ||||
							
								
								
									
										3
									
								
								tests/data/command120.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/data/command120.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE file" | ||||
|  | ||||
|  | ||||
							
								
								
									
										1
									
								
								tests/data/command121.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/command121.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE after_transfer" -Q "DELE before_transfer" | ||||
							
								
								
									
										1
									
								
								tests/data/command28.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/command28.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| --globoff http://%HOSTIP:%HOSTPORT/wantit/{}[]/28 | ||||
							
								
								
									
										1
									
								
								tests/data/command29.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/command29.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| -C 200 http://%HOSTIP:%HOSTPORT/29 | ||||
							
								
								
									
										1
									
								
								tests/data/command30.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/command30.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| http://%HOSTIP:%HOSTPORT/30 | ||||
							
								
								
									
										2
									
								
								tests/data/command31.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/data/command31.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| http://%HOSTIP:%HOSTPORT/31 -d mooo=fooo -L | ||||
|  | ||||
							
								
								
									
										2
									
								
								tests/data/command32.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/data/command32.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| http://%HOSTIP:%HOSTPORT/32 -d mooo=fooo -L | ||||
|  | ||||
							
								
								
									
										3
									
								
								tests/data/command33.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/data/command33.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| http://%HOSTIP:%HOSTPORT/33 -Tdata/extra33.txt -C 50 | ||||
|  | ||||
|  | ||||
							
								
								
									
										1
									
								
								tests/data/error30.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/error30.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| 18 | ||||
							
								
								
									
										15
									
								
								tests/data/extra33.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/data/extra33.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
							
								
								
									
										1
									
								
								tests/data/name120.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name120.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| ftp download with post-quote delete operation | ||||
							
								
								
									
										1
									
								
								tests/data/name121.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name121.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| ftp download with post- and pre-transfer delete operations | ||||
							
								
								
									
										1
									
								
								tests/data/name28.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name28.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| --globoff with {][} in URL | ||||
							
								
								
									
										1
									
								
								tests/data/name29.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name29.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| HTTP download resume with Content-Length validity | ||||
							
								
								
									
										1
									
								
								tests/data/name30.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name30.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| HTTP GET uncomplete document | ||||
							
								
								
									
										1
									
								
								tests/data/name31.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name31.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| HTTP POST and follow Location: (error 301) | ||||
							
								
								
									
										1
									
								
								tests/data/name32.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name32.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| HTTP POST and follow Location: (error 303) | ||||
							
								
								
									
										1
									
								
								tests/data/name33.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/data/name33.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| HTTP PUT resume | ||||
							
								
								
									
										6
									
								
								tests/data/prot120.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/data/prot120.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| USER anonymous | ||||
| PASS curl_by_daniel@haxx.se | ||||
| PASV | ||||
| TYPE I | ||||
| RETR 106 | ||||
| DELE file | ||||
							
								
								
									
										7
									
								
								tests/data/prot121.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/data/prot121.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| USER anonymous | ||||
| PASS curl_by_daniel@haxx.se | ||||
| DELE before_transfer | ||||
| PASV | ||||
| TYPE I | ||||
| RETR 106 | ||||
| DELE after_transfer | ||||
							
								
								
									
										5
									
								
								tests/data/prot28.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/data/prot28.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| GET /wantit/{}[]/28 HTTP/1.0 | ||||
| Host: 127.0.0.1:8999 | ||||
| Pragma: no-cache | ||||
| Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* | ||||
|  | ||||
							
								
								
									
										7
									
								
								tests/data/prot29.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/data/prot29.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| GET /29 HTTP/1.0 | ||||
| Range: bytes=200- | ||||
| User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled) | ||||
| Host: 127.0.0.1:8999 | ||||
| Pragma: no-cache | ||||
| Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* | ||||
|  | ||||
							
								
								
									
										6
									
								
								tests/data/prot30.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/data/prot30.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| GET /30 HTTP/1.0 | ||||
| User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled) | ||||
| Host: 127.0.0.1:8999 | ||||
| Pragma: no-cache | ||||
| Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* | ||||
|  | ||||
							
								
								
									
										9
									
								
								tests/data/prot31.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/data/prot31.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| POST /moo/moo/moo/310002 HTTP/1.0 | ||||
| User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled) | ||||
| Host: 127.0.0.1:8999 | ||||
| Pragma: no-cache | ||||
| Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* | ||||
| Content-Length: 9 | ||||
| Content-Type: application/x-www-form-urlencoded | ||||
|  | ||||
| mooo=fooo | ||||
							
								
								
									
										6
									
								
								tests/data/prot32.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/data/prot32.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| GET /moo/moo/moo/320002 HTTP/1.0 | ||||
| User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled) | ||||
| Host: 127.0.0.1:8999 | ||||
| Pragma: no-cache | ||||
| Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* | ||||
|  | ||||
							
								
								
									
										18
									
								
								tests/data/prot33.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/data/prot33.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| PUT /33 HTTP/1.0 | ||||
| Content-Range: bytes 50-149/150 | ||||
| User-Agent: curl/7.6 (sparc-sun-solaris2.7) libcurl 7.6-pre4 (SSL 0.9.6) (krb4 enabled) | ||||
| Host: 127.0.0.1:8999 | ||||
| Pragma: no-cache | ||||
| Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* | ||||
| Content-Length: 100 | ||||
|  | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| 012345678 | ||||
| @@ -2,5 +2,6 @@ HTTP/1.1 301 This is a weirdo text message | ||||
| Date: Thu, 09 Nov 2010 14:49:00 GMT | ||||
| Server: test-server/fake | ||||
| Location: data/110002.txt?coolsite=yes | ||||
| Connection: close | ||||
|  | ||||
| This server reply is for testing a simple Location: following | ||||
|   | ||||
| @@ -2,6 +2,7 @@ HTTP/1.1 301 This is a weirdo text message | ||||
| Date: Thu, 09 Nov 2010 14:49:00 GMT | ||||
| Server: test-server/fake | ||||
| Location: data/110002.txt?coolsite=yes | ||||
| Connection: close | ||||
|  | ||||
| HTTP/1.1 200 Followed here fine | ||||
| Date: Thu, 09 Nov 2010 14:49:00 GMT | ||||
|   | ||||
							
								
								
									
										6
									
								
								tests/data/reply120.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/data/reply120.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| data | ||||
|     to | ||||
|       see | ||||
| that FTP | ||||
| works | ||||
|   so does it? | ||||
							
								
								
									
										6
									
								
								tests/data/reply121.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/data/reply121.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| data | ||||
|     to | ||||
|       see | ||||
| that FTP | ||||
| works | ||||
|   so does it? | ||||
							
								
								
									
										5
									
								
								tests/data/reply28.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/data/reply28.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| HTTP/1.1 200 OK | ||||
| Server: fake | ||||
|  | ||||
| {}[] in the URL is not legal | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user