Compare commits
	
		
			275 Commits
		
	
	
		
			curl-7_9_5
			...
			curl-7_9_7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | bbe10cb0cb | ||
|   | daba8f3a70 | ||
|   | 1458c3668d | ||
|   | 980a47b42b | ||
|   | f7ca561b06 | ||
|   | cacd756efd | ||
|   | 8539e76cb9 | ||
|   | 3bbf694d5a | ||
|   | 44debdde62 | ||
|   | c6cf2b8e93 | ||
|   | 69c5452b25 | ||
|   | d321056e8d | ||
|   | d9a1a59f22 | ||
|   | 0b898b5a8a | ||
|   | a9e0885be0 | ||
|   | 57ff28c9b7 | ||
|   | 86cc34c0de | ||
|   | 39028f1bd4 | ||
|   | 71f4c05665 | ||
|   | 9ef9797998 | ||
|   | ab9374de57 | ||
|   | 913e997061 | ||
|   | 8e50d6b6f3 | ||
|   | 2db0744a7b | ||
|   | 2de0028349 | ||
|   | 35d04c5398 | ||
|   | b1becd0ed5 | ||
|   | bd9650bc81 | ||
|   | 969a25d1b2 | ||
|   | f144f77ba7 | ||
|   | abea1f8910 | ||
|   | 8eaa7fec76 | ||
|   | fdace647e8 | ||
|   | d7531c18fc | ||
|   | ef3f978784 | ||
|   | e410860e0e | ||
|   | c64fca1b0c | ||
|   | 15b2a3af91 | ||
|   | 8358505b6d | ||
|   | 1c42779845 | ||
|   | 32823f17e0 | ||
|   | e1c2e3f5e9 | ||
|   | 044755b30f | ||
|   | 9aa22399a8 | ||
|   | f564905ac4 | ||
|   | 00e4f81446 | ||
|   | 8927ddec16 | ||
|   | f6525ae200 | ||
|   | 0be7944d66 | ||
|   | 47819ea86e | ||
|   | 96ce3461ad | ||
|   | 8b6d555421 | ||
|   | 3b9ef8dfc8 | ||
|   | db6d4bcf47 | ||
|   | 471f1d694f | ||
|   | 495f6f6bd3 | ||
|   | 36e35b6f60 | ||
|   | 192606bc4b | ||
|   | 53a9fdf078 | ||
|   | ef436bdbe8 | ||
|   | 72d722b07b | ||
|   | 21fc402c01 | ||
|   | 381f77756d | ||
|   | a386562d9a | ||
|   | 2bc84fb163 | ||
|   | 08f8917acb | ||
|   | 62d205a2ec | ||
|   | 29e873b12d | ||
|   | 95f78080ab | ||
|   | 9549cfde02 | ||
|   | 2361aabbef | ||
|   | e0cc8d2ce9 | ||
|   | 53c0e97117 | ||
|   | bb44791bf3 | ||
|   | 9ebcfe9dff | ||
|   | f339bf613c | ||
|   | b00c59816d | ||
|   | a00918116d | ||
|   | d26c318321 | ||
|   | eb8770506f | ||
|   | c06171a802 | ||
|   | 5528c1eaa5 | ||
|   | 93516effe4 | ||
|   | 38e518c710 | ||
|   | 3f6133be27 | ||
|   | c3bfb355c5 | ||
|   | c69dd14cbc | ||
|   | 7954652b80 | ||
|   | ca35b39900 | ||
|   | 09df9b90c3 | ||
|   | 308ae5cbf2 | ||
|   | 1cd5cdfccb | ||
|   | 606e7fd744 | ||
|   | e8109b09b1 | ||
|   | 536ea60d73 | ||
|   | 3390b6446c | ||
|   | bfc7f1e4ac | ||
|   | 8ba410a56e | ||
|   | 14d1da3ae0 | ||
|   | 2a72641a0b | ||
|   | 9c4e5dc3ee | ||
|   | 540e5ffa90 | ||
|   | c1a57591ee | ||
|   | 1a4f72dd4f | ||
|   | c3c8bbd3b2 | ||
|   | fb7d34cea8 | ||
|   | 0866c1b52d | ||
|   | 136f728b49 | ||
|   | 5d28a857a4 | ||
|   | edbe0d166c | ||
|   | 4db8c8b1a3 | ||
|   | 2b16b8604a | ||
|   | f630929810 | ||
|   | 016abdfef6 | ||
|   | fd915609cd | ||
|   | 064697fde6 | ||
|   | a03fd7b81c | ||
|   | 1cfcbc50a6 | ||
|   | ea1f138c08 | ||
|   | d560207ea1 | ||
|   | 90b51831fd | ||
|   | 38ed8938d8 | ||
|   | 547e91dbf0 | ||
|   | 04da96e044 | ||
|   | 4a7def101b | ||
|   | 541e5a3b82 | ||
|   | 5af61716aa | ||
|   | 6f3e0051c3 | ||
|   | 703ecc3521 | ||
|   | 67b0f9aacd | ||
|   | 854277bae5 | ||
|   | ca9760756a | ||
|   | f1f993a25b | ||
|   | eb0f727818 | ||
|   | dc3d0289d6 | ||
|   | bd830c6f4d | ||
|   | 51d602f973 | ||
|   | 30d5401f31 | ||
|   | ab6b0f9843 | ||
|   | c560327f26 | ||
|   | 28939dd45c | ||
|   | 3853e3d6f3 | ||
|   | 6062a1bd68 | ||
|   | 8d94688fd1 | ||
|   | 6b4532b592 | ||
|   | 286fb6f645 | ||
|   | 340caf5da3 | ||
|   | 171c4fd49f | ||
|   | b8a0fb1dfe | ||
|   | e65993bccb | ||
|   | 7ffb4660ec | ||
|   | 974f314f57 | ||
|   | 4cec22fa19 | ||
|   | 069477d35c | ||
|   | eaff1a344e | ||
|   | 1fe1e39a88 | ||
|   | 33b06f56f0 | ||
|   | 61a84abe2a | ||
|   | 3d03100079 | ||
|   | 5297a52bf0 | ||
|   | 88631276e8 | ||
|   | 2c0d9ad64c | ||
|   | 5c691ed835 | ||
|   | f73864a045 | ||
|   | 94da04fcac | ||
|   | 5f758fbd11 | ||
|   | fb29529a52 | ||
|   | 3cd2673077 | ||
|   | d242214e18 | ||
|   | 468b787272 | ||
|   | cfdb6f851c | ||
|   | 7886f120f3 | ||
|   | 76fe69b133 | ||
|   | e1bae4fc7e | ||
|   | bc9705f758 | ||
|   | c819e234b8 | ||
|   | ce021b79a7 | ||
|   | 805a2f6f99 | ||
|   | eb78400b53 | ||
|   | 4852f9ffbd | ||
|   | c8d2ad2513 | ||
|   | 9f374c2050 | ||
|   | 5799852424 | ||
|   | 6417fa95cf | ||
|   | 61f6284a35 | ||
|   | 6b1a1a62a3 | ||
|   | feacb4b481 | ||
|   | fe3c874001 | ||
|   | d9459b54d9 | ||
|   | 017be8a882 | ||
|   | b86e543a13 | ||
|   | c2d4fd876c | ||
|   | 58cad04bbb | ||
|   | 9bb64d6827 | ||
|   | 4441df90c1 | ||
|   | f51f2417c5 | ||
|   | aad617647d | ||
|   | 49c0d62dda | ||
|   | f752098ba5 | ||
|   | a4477b9e4b | ||
|   | ad3cef0fc8 | ||
|   | d89dbe5bd6 | ||
|   | b0475dbdbc | ||
|   | 60b2e74fa3 | ||
|   | cda16297d1 | ||
|   | d6c9a72e15 | ||
|   | 4d7b1512c1 | ||
|   | d8a35d745e | ||
|   | e22657ea13 | ||
|   | d06d6b5534 | ||
|   | cec8ab1fde | ||
|   | 9fc62a8dd0 | ||
|   | 61540b98c2 | ||
|   | 465ae39e86 | ||
|   | 01f04b9a41 | ||
|   | 34f9ab1046 | ||
|   | 699876778b | ||
|   | 8fc5a0d19e | ||
|   | 62b5926d58 | ||
|   | 4d1037f385 | ||
|   | e4addb3975 | ||
|   | 2aef351980 | ||
|   | d88c153c7d | ||
|   | 9e9883082e | ||
|   | 71440df4c7 | ||
|   | 80b004a57d | ||
|   | ea8476a2dc | ||
|   | cb85ca18ab | ||
|   | f1103b95cf | ||
|   | aa5ff53bcf | ||
|   | 907dabed5d | ||
|   | 0cacbc892c | ||
|   | 6753c3c715 | ||
|   | 36e1363e3d | ||
|   | d1a711eb6a | ||
|   | d8dea4dcc7 | ||
|   | ca161737bc | ||
|   | 3612c3774e | ||
|   | e6a65bb3ef | ||
|   | ff291eee48 | ||
|   | 66b8f48a88 | ||
|   | 634760cbdc | ||
|   | a23a897ad2 | ||
|   | d9c244278d | ||
|   | b6c4185b27 | ||
|   | 5896d35e72 | ||
|   | b4dfdd8bbc | ||
|   | e6ed3478ea | ||
|   | db08d9c6b9 | ||
|   | 9490278ece | ||
|   | fd8bf5f171 | ||
|   | c9bc14a222 | ||
|   | 63708cbfb0 | ||
|   | d9f307623c | ||
|   | 540f77a627 | ||
|   | 71bb2d0b8b | ||
|   | 87dc44e434 | ||
|   | 29e0fcd091 | ||
|   | 2e9a798f09 | ||
|   | b32a39f44f | ||
|   | d86f9611b3 | ||
|   | 6a62fc4a40 | ||
|   | 7cdd6455d7 | ||
|   | e4fefd088d | ||
|   | 95e601e2b1 | ||
|   | b1ffe7b74a | ||
|   | 417c8fb602 | ||
|   | 85efa64c31 | ||
|   | d8cb026e80 | ||
|   | 41dd5121f0 | ||
|   | 94482d7ca5 | ||
|   | 4d0e51aead | ||
|   | ae8a8c8ba4 | ||
|   | 7d043f46d5 | ||
|   | cbca19d6c2 | 
							
								
								
									
										1957
									
								
								CHANGES.2001
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1957
									
								
								CHANGES.2001
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -2,7 +2,7 @@ | |||||||
| # $Id$ | # $Id$ | ||||||
| # | # | ||||||
|  |  | ||||||
| AUTOMAKE_OPTIONS = foreign no-dependencies | AUTOMAKE_OPTIONS = foreign | ||||||
|  |  | ||||||
| EXTRA_DIST =						\ | EXTRA_DIST =						\ | ||||||
| 	CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt	\ | 	CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt	\ | ||||||
| @@ -10,7 +10,7 @@ EXTRA_DIST =						\ | |||||||
|  |  | ||||||
| bin_SCRIPTS = curl-config | bin_SCRIPTS = curl-config | ||||||
|  |  | ||||||
| SUBDIRS = docs lib src include tests packages multi | SUBDIRS = docs lib src include tests packages | ||||||
|  |  | ||||||
| # create a root makefile in the distribution: | # create a root makefile in the distribution: | ||||||
| dist-hook: | dist-hook: | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| #                            | (__| |_| |  _ <| |___  | #                            | (__| |_| |  _ <| |___  | ||||||
| #                             \___|\___/|_| \_\_____| | #                             \___|\___/|_| \_\_____| | ||||||
| # | # | ||||||
| # Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. | # Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
| # | # | ||||||
| # In order to be useful for every potential user, curl and libcurl are | # In order to be useful for every potential user, curl and libcurl are | ||||||
| # dual-licensed under the MPL and the MIT/X-derivate licenses. | # dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								README
									
									
									
									
									
								
							| @@ -19,9 +19,10 @@ README | |||||||
|  |  | ||||||
|   Study the LEGAL file for distribution terms and similar. |   Study the LEGAL file for distribution terms and similar. | ||||||
|  |  | ||||||
|   Always try the Curl web site for the latest news: |   Visit the curl web site or mirror for the latest news: | ||||||
|  |  | ||||||
|         http://curl.haxx.se |         http://curl.haxx.se/ | ||||||
|  |         http://curl.sf.net/ | ||||||
|  |  | ||||||
|   The official download mirror sites are: |   The official download mirror sites are: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,4 +8,4 @@ die(){ | |||||||
| aclocal           || die "The command 'aclocal' failed" | aclocal           || die "The command 'aclocal' failed" | ||||||
| autoheader        || die "The command 'autoheader' failed" | autoheader        || die "The command 'autoheader' failed" | ||||||
| autoconf          || die "The command 'autoconf' failed" | autoconf          || die "The command 'autoconf' failed" | ||||||
| automake          || die "The command 'automake $MAKEFILES' failed" | automake -a       || die "The command 'automake $MAKEFILES' failed" | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ AC_PREREQ(2.50) | |||||||
| dnl First some basic init macros | dnl First some basic init macros | ||||||
| AC_INIT | AC_INIT | ||||||
| AC_CONFIG_SRCDIR([lib/urldata.h]) | AC_CONFIG_SRCDIR([lib/urldata.h]) | ||||||
| AM_CONFIG_HEADER(lib/config.h src/config.h) | AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h) | ||||||
|  |  | ||||||
| dnl figure out the libcurl version | dnl figure out the libcurl version | ||||||
| VERSION=`sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h` | VERSION=`sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h` | ||||||
| @@ -594,13 +594,14 @@ dnl AC_SUBST(RANLIB) | |||||||
| AC_CONFIG_FILES([Makefile \ | AC_CONFIG_FILES([Makefile \ | ||||||
| 	   docs/Makefile \ | 	   docs/Makefile \ | ||||||
|            docs/examples/Makefile \ |            docs/examples/Makefile \ | ||||||
|  |            docs/libcurl/Makefile \ | ||||||
| 	   include/Makefile \ | 	   include/Makefile \ | ||||||
| 	   include/curl/Makefile \ | 	   include/curl/Makefile \ | ||||||
| 	   src/Makefile \ | 	   src/Makefile \ | ||||||
| 	   multi/Makefile \ |  | ||||||
|            lib/Makefile \ |            lib/Makefile \ | ||||||
|            tests/Makefile \ |            tests/Makefile \ | ||||||
|            tests/data/Makefile \ |            tests/data/Makefile \ | ||||||
|  |            tests/server/Makefile \ | ||||||
| 	   packages/Makefile \ | 	   packages/Makefile \ | ||||||
| 	   packages/Win32/Makefile \ | 	   packages/Win32/Makefile \ | ||||||
| 	   packages/Win32/cygwin/Makefile \ | 	   packages/Win32/cygwin/Makefile \ | ||||||
| @@ -609,6 +610,8 @@ AC_CONFIG_FILES([Makefile \ | |||||||
| 	   packages/Linux/RPM/curl.spec \ | 	   packages/Linux/RPM/curl.spec \ | ||||||
| 	   packages/Linux/RPM/curl-ssl.spec \ | 	   packages/Linux/RPM/curl-ssl.spec \ | ||||||
|            packages/Solaris/Makefile \ |            packages/Solaris/Makefile \ | ||||||
|  |            packages/EPM/curl.list \ | ||||||
|  |            packages/EPM/Makefile \ | ||||||
|            curl-config |            curl-config | ||||||
| ]) | ]) | ||||||
| AC_OUTPUT | AC_OUTPUT | ||||||
|   | |||||||
							
								
								
									
										91
									
								
								docs/BINDINGS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								docs/BINDINGS
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  |                                   _   _ ____  _      | ||||||
|  |                               ___| | | |  _ \| |     | ||||||
|  |                              / __| | | | |_) | |     | ||||||
|  |                             | (__| |_| |  _ <| |___  | ||||||
|  |                              \___|\___/|_| \_\_____| | ||||||
|  |  | ||||||
|  |                                libcurl bindings | ||||||
|  |  | ||||||
|  | Creative people have written particular bindings or interfaces for various | ||||||
|  | environments and programming languages. Using one of these allows you to take | ||||||
|  | advantage of curl powers from within your favourite language or system. | ||||||
|  |  | ||||||
|  | This is a list of all known interfaces as of this writing. | ||||||
|  |  | ||||||
|  | The bindings listed below are not part of the curl/libcurl distribution | ||||||
|  | archives, but must be downloaded and installed separately. | ||||||
|  |  | ||||||
|  | Basic | ||||||
|  |  | ||||||
|  |   ScriptBasic bindings to libcurl. Writtten by Peter Verhas. | ||||||
|  |   http://scriptbasic.com/ | ||||||
|  |  | ||||||
|  | C++ | ||||||
|  |  | ||||||
|  |   Maintained by Jean-Philippe Barrette-LaPierre. | ||||||
|  |   http://curl.haxx.se/libcurl/cplusplus/ | ||||||
|  |  | ||||||
|  | Cocoa | ||||||
|  |  | ||||||
|  |   Written by Dan Wood. | ||||||
|  |   http://curlhandle.sourceforge.net/ | ||||||
|  |  | ||||||
|  | Dylan | ||||||
|  |  | ||||||
|  |   Written by Chris Double. | ||||||
|  |   http://dylanlibs.sourceforge.net/ | ||||||
|  |  | ||||||
|  | Java | ||||||
|  |  | ||||||
|  |   Written by Daniel Stenberg. | ||||||
|  |   http://curl.haxx.se/libcurl/java/ | ||||||
|  |  | ||||||
|  | Lua | ||||||
|  |  | ||||||
|  |   Written by Steve Dekorte. | ||||||
|  |   http://curl.haxx.se/libcurl/lua/ | ||||||
|  |  | ||||||
|  | Pascal | ||||||
|  |  | ||||||
|  |   Free Pascal binding written by Jeffrey Pohlmeyer. | ||||||
|  |   http://houston.quik.com/jkp/curlpas/ | ||||||
|  |  | ||||||
|  | Perl | ||||||
|  |  | ||||||
|  |   Maintained by Cris Bailiff. | ||||||
|  |   http://curl.haxx.se/libcurl/perl/ | ||||||
|  |  | ||||||
|  | PHP | ||||||
|  |  | ||||||
|  |   Written by Sterling Hughes. | ||||||
|  |   http://curl.haxx.se/libcurl/php/ | ||||||
|  |  | ||||||
|  | PostgreSQL | ||||||
|  |  | ||||||
|  |   Written by Gian Paolo Ciceri. | ||||||
|  |   http://gborg.postgresql.org/project/pgcurl/projdisplay.php | ||||||
|  |  | ||||||
|  | Python | ||||||
|  |  | ||||||
|  |   Written by Kjetil Jacobsen. | ||||||
|  |   http://pycurl.sourceforge.net/ | ||||||
|  |  | ||||||
|  | Rexx | ||||||
|  |  | ||||||
|  |   Written Mark Hessling.  | ||||||
|  |   http://rexxcurl.sourceforge.net/ | ||||||
|  |  | ||||||
|  | Ruby | ||||||
|  |  | ||||||
|  |   Written by Hirotaka Matsuyuki.  | ||||||
|  |   http://www.d1.dion.ne.jp/~matuyuki/ruby.html | ||||||
|  |  | ||||||
|  | Scheme | ||||||
|  |  | ||||||
|  |   Bigloo binding written by Kirill Lisovsky. | ||||||
|  |   http://curl.haxx.se/libcurl/scheme/ | ||||||
|  |  | ||||||
|  | Tcl | ||||||
|  |  | ||||||
|  |   Written by Andr<64>s Garc<72>a.  | ||||||
|  |   http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html | ||||||
							
								
								
									
										42
									
								
								docs/BUGS
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								docs/BUGS
									
									
									
									
									
								
							| @@ -8,28 +8,44 @@ $Id$ | |||||||
| BUGS | BUGS | ||||||
|  |  | ||||||
|   Curl and libcurl have grown substantially since the beginning. At the time |   Curl and libcurl have grown substantially since the beginning. At the time | ||||||
|   of writing (mid March 2001), there are 23000 lines of source code, and by |   of writing (end of April 2002), there are 32000 lines of source code, and by | ||||||
|   the time you read this it has probably grown even more. |   the time you read this it has probably grown even more. | ||||||
|  |  | ||||||
|   Of course there are lots of bugs left. And lots of misfeatures. |   Of course there are lots of bugs left. And lots of misfeatures. | ||||||
|  |  | ||||||
|   To help us make curl the stable and solid product we want it to be, we need |   To help us make curl the stable and solid product we want it to be, we need | ||||||
|   bug reports and bug fixes. If you can't fix a bug yourself and submit a fix |   bug reports and bug fixes. | ||||||
|   for it, try to report an as detailed report as possible to the curl mailing |  | ||||||
|   list to allow one of us to have a go at a solution. You should also post | WHERE TO REPORT | ||||||
|   your bug/problem at curl's bug tracking system over at |  | ||||||
|  |   If you can't fix a bug yourself and submit a fix for it, try to report an as | ||||||
|  |   detailed report as possible to the curl mailing list to allow one of us to | ||||||
|  |   have a go at a solution. You should also post your bug/problem at curl's bug | ||||||
|  |   tracking system over at | ||||||
|  |  | ||||||
|         http://sourceforge.net/bugs/?group_id=976 |         http://sourceforge.net/bugs/?group_id=976 | ||||||
|  |  | ||||||
|   When reporting a bug, you should include information that will help us |   (but please read the section below first before doing that) | ||||||
|   understand what's wrong, what you expected to happen and how to repeat the |  | ||||||
|   bad behavior. You therefore need to supply your operating system's name and |  | ||||||
|   version number (uname -a under a unix is fine), what version of curl you're |  | ||||||
|   using (curl -V is fine), what URL you were working with and anything else |  | ||||||
|   you think matters. |  | ||||||
|  |  | ||||||
|   Since curl deals with networks, it often helps us a lot if you include a | WHAT TO REPORT | ||||||
|   protocol debug dump with your bug report. The output you get by using the -v |  | ||||||
|  |   When reporting a bug, you should include information that will help us | ||||||
|  |   understand what's wrong what you expected to happen and how to repeat the | ||||||
|  |   bad behavior. You therefore need to tell us: | ||||||
|  |  | ||||||
|  |    - your operating system's name and version number (uname -a under a unix | ||||||
|  |      is fine) | ||||||
|  |    - what version of curl you're using (curl -V is fine) | ||||||
|  |    - what URL you were working with (if possible), at least which protocol | ||||||
|  |  | ||||||
|  |   and anything and everything else you think matters. Tell us what you | ||||||
|  |   expected to happen, tell use what did happen, tell us how you could make it | ||||||
|  |   work another way. Dig around, try out, test. Then include all the tiny bits | ||||||
|  |   and pieces in your report. You will benefit from this yourself, as it will | ||||||
|  |   enable us to help you quicker and more accurately. | ||||||
|  |  | ||||||
|  |   Since curl deals with networks, it often helps us if you include a protocol | ||||||
|  |   debug dump with your bug report. The output you get by using the -v | ||||||
|   flag. Usually, you also get more info by using -i so that is likely to be |   flag. Usually, you also get more info by using -i so that is likely to be | ||||||
|   useful when reporting bugs as well. |   useful when reporting bugs as well. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								docs/FAQ
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								docs/FAQ
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| Updated: January 22, 2002 (http://curl.haxx.se/docs/faq.shtml) | Updated: April 27, 2002 (http://curl.haxx.se/docs/faq.shtml) | ||||||
|                                   _   _ ____  _      |                                   _   _ ____  _      | ||||||
|                               ___| | | |  _ \| |     |                               ___| | | |  _ \| |     | ||||||
|                              / __| | | | |_) | |     |                              / __| | | | |_) | |     | ||||||
| @@ -15,6 +15,7 @@ FAQ | |||||||
|   1.5 Who makes cURL? |   1.5 Who makes cURL? | ||||||
|   1.6 What do you get for making cURL? |   1.6 What do you get for making cURL? | ||||||
|   1.7 What about CURL from curl.com? |   1.7 What about CURL from curl.com? | ||||||
|  |   1.8 I have a problem who do I mail? | ||||||
|  |  | ||||||
|  2. Install Related Problems |  2. Install Related Problems | ||||||
|   2.1 configure doesn't find OpenSSL even when it is installed |   2.1 configure doesn't find OpenSSL even when it is installed | ||||||
| @@ -37,6 +38,7 @@ FAQ | |||||||
|   3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? |   3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? | ||||||
|   3.11 How do I POST with a different Content-Type? |   3.11 How do I POST with a different Content-Type? | ||||||
|   3.12 Why do FTP specific features over HTTP proxy fail? |   3.12 Why do FTP specific features over HTTP proxy fail? | ||||||
|  |   3.13 Why does my single/double quotes fail? | ||||||
|  |  | ||||||
|  4. Running Problems |  4. Running Problems | ||||||
|   4.1 Problems connecting to SSL servers. |   4.1 Problems connecting to SSL servers. | ||||||
| @@ -192,6 +194,21 @@ FAQ | |||||||
|   We recognize that we will be living in parallel with curl.com and wish them |   We recognize that we will be living in parallel with curl.com and wish them | ||||||
|   every success. |   every success. | ||||||
|  |  | ||||||
|  |   1.8 I have a problem who do I mail? | ||||||
|  |  | ||||||
|  |   Please do not attempt to mail any single individual unless you really need | ||||||
|  |   to. Keep curl-related questions on a suitable mailing list. All available | ||||||
|  |   mailing lists are listed in the MANUAL document and online at | ||||||
|  |   http://curl.haxx.se/mail/ | ||||||
|  |  | ||||||
|  |   Keeping curl-related questions and dicussions on mailing lists allows others | ||||||
|  |   to join in and help, to share their ideas, contribute their suggestions and | ||||||
|  |   spread their wisdom. Keeping discussions on public mailing lists also allows | ||||||
|  |   for others to learn from this (both current and future users thanks to the | ||||||
|  |   web based archives of the mailing lists), thus saving us from having to | ||||||
|  |   repeat ourselves even more. Thanks for respecting this. | ||||||
|  |  | ||||||
|  |  | ||||||
| 2. Install Related Problems | 2. Install Related Problems | ||||||
|  |  | ||||||
|   2.1. configure doesn't find OpenSSL even when it is installed |   2.1. configure doesn't find OpenSSL even when it is installed | ||||||
| @@ -341,10 +358,6 @@ FAQ | |||||||
|   may very well opt to use such an interface instead of using the command line |   may very well opt to use such an interface instead of using the command line | ||||||
|   tool. |   tool. | ||||||
|  |  | ||||||
|   At the time of writing, there are bindings for the five language mentioned |  | ||||||
|   above, but chances are there are even more by the time you read this. Or you |  | ||||||
|   may be able you write your own wrapper for a not-yet supported language! |  | ||||||
|  |  | ||||||
|   Find out more about which languages that support curl directly, and how to |   Find out more about which languages that support curl directly, and how to | ||||||
|   install and use them, in the libcurl section of the curl web site: |   install and use them, in the libcurl section of the curl web site: | ||||||
|  |  | ||||||
| @@ -383,6 +396,30 @@ FAQ | |||||||
|   and is generally not available as proxy admins usually disable tunneling to |   and is generally not available as proxy admins usually disable tunneling to | ||||||
|   other ports than 443 (which is used for HTTPS access through proxies). |   other ports than 443 (which is used for HTTPS access through proxies). | ||||||
|  |  | ||||||
|  |   3.13 Why does my single/double quotes fail? | ||||||
|  |  | ||||||
|  |   To specify a command line option that includes spaces, you might need to | ||||||
|  |   put the entire option within quotes. Like in: | ||||||
|  |  | ||||||
|  |    curl -d " with spaces " url.com | ||||||
|  |    | ||||||
|  |   or perhaps | ||||||
|  |  | ||||||
|  |    curl -d ' with spaces ' url.com | ||||||
|  |  | ||||||
|  |   Exactly what kind of quotes and how to do this is entirely up to the shell | ||||||
|  |   or command line interepreter that you are using. For most unix shells, you | ||||||
|  |   can more or less pick either single (') or double (") quotes. For | ||||||
|  |   Windows/DOS prompts I believe you're forced to use double (") quotes. | ||||||
|  |  | ||||||
|  |   Please study the documentaion for your particular environment. Examples in | ||||||
|  |   the curl docs will use a mix of both these ones as shown above. You must | ||||||
|  |   adjust them to work in your environment. | ||||||
|  |  | ||||||
|  |   Remember that curl works and runs on more operating systems than most single | ||||||
|  |   individuals have ever tried. | ||||||
|  |  | ||||||
|  |  | ||||||
| 4. Running Problems | 4. Running Problems | ||||||
|  |  | ||||||
|   4.1. Problems connecting to SSL servers. |   4.1. Problems connecting to SSL servers. | ||||||
| @@ -516,12 +553,8 @@ FAQ | |||||||
|   particular platform, try contacting the person who built the package/archive |   particular platform, try contacting the person who built the package/archive | ||||||
|   you have. |   you have. | ||||||
|  |  | ||||||
|   If there is a bug, post a bug report in the Curl Bug Track System over at |   If there is a bug, read the BUGS document first. Then report it as described | ||||||
|   http://sourceforge.net/bugs/?group_id=976 |   in there. | ||||||
|  |  | ||||||
|   Always include as many details you can think of, including curl version, |  | ||||||
|   operating system name and version and complete instructions how to repeat |  | ||||||
|   the bug. |  | ||||||
|  |  | ||||||
|   4.9. Curl can't authenticate to the server that requires NTLM? |   4.9. Curl can't authenticate to the server that requires NTLM? | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								docs/INSTALL
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								docs/INSTALL
									
									
									
									
									
								
							| @@ -201,33 +201,33 @@ Win32 | |||||||
|  |  | ||||||
|       Microsoft command line style |       Microsoft command line style | ||||||
|       ---------------------------- |       ---------------------------- | ||||||
|         Please read the OpenSSL documentation on how to compile and install |  | ||||||
|         the OpenSSL library.  This generates the libeay32.dll and ssleay32.dll |  | ||||||
|         files in the out32dll subdirectory in the OpenSSL home directory.  If |  | ||||||
|         you compiled OpenSSL static libraries (libeay32.lib, ssleay32.lib, |  | ||||||
|         RSAglue.lib) they are created in the out32 subdirectory. |  | ||||||
|  |  | ||||||
|         Run the 'vcvars32.bat' file to get the proper environment variables |         Please read the OpenSSL documentation on how to compile and install | ||||||
|         set. The vcvars32.bat file is part of the Microsoft development |         the OpenSSL libraries.  The build process of OpenSSL generates the | ||||||
|         environment and you may find it in 'C:\Program Files\Microsoft Visual |         libeay32.dll and ssleay32.dll files in the out32dll subdirectory in | ||||||
|         Studio\vc98\bin' if you installed Visual C/C++ 6 in the default |         the OpenSSL home directory.  OpenSSL static libraries (libeay32.lib, | ||||||
|         directory. |         ssleay32.lib, RSAglue.lib) are created in the out32 subdirectory. | ||||||
|  |  | ||||||
|  |         Run the 'vcvars32.bat' file to get a proper environment. The | ||||||
|  |         vcvars32.bat file is part of the Microsoft development environment and | ||||||
|  |         you may find it in 'C:\Program Files\Microsoft Visual Studio\vc98\bin' | ||||||
|  |         provided that you installed Visual C/C++ 6 in the default directory. | ||||||
|  |  | ||||||
|         Before running nmake define the OPENSSL_PATH environment variable with |         Before running nmake define the OPENSSL_PATH environment variable with | ||||||
|         the root/base directory of OpenSSL, for example: |         the root/base directory of OpenSSL, for example: | ||||||
|  |  | ||||||
|           set OPENSSL_PATH=c:\openssl-0.9.6b |           set OPENSSL_PATH=c:\openssl-0.9.6b | ||||||
|  |  | ||||||
|         Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in the curl's root |         Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root | ||||||
|         directory.  'nmake vc-ssl' will create a libcurl static and dynamic |         directory.  'nmake vc-ssl' will create a libcurl static and dynamic | ||||||
|         libraries in the lib subdirectory, as well as a statically linked |         libraries in the lib subdirectory, as well as a statically linked | ||||||
|         version of curl.exe in the scr subdirectory.  This statically linked |         version of curl.exe in the src subdirectory.  This statically linked | ||||||
|         version is a standalone executable not requiring any DLL at |         version is a standalone executable not requiring any DLL at | ||||||
|         runtime. This making method requires that you have build the static |         runtime. This make method requires that you have the static OpenSSL | ||||||
|         libraries of OpenSSL available in OpenSSL's out32 subdirectory. |         libraries available in OpenSSL's out32 subdirectory. | ||||||
| 	'nmake vc-ssl-dll' creates the libcurl dynamic library and | 	'nmake vc-ssl-dll' creates the libcurl dynamic library and | ||||||
| 	links curl.exe against libcurl and OpenSSL dynamically. | 	links curl.exe against libcurl and OpenSSL dynamically. | ||||||
| 	This executables requires libcurl.dll and the OpenSSL DLLs | 	This executable requires libcurl.dll and the OpenSSL DLLs | ||||||
| 	at runtime. | 	at runtime. | ||||||
|  |  | ||||||
|       Microsoft / Borland style |       Microsoft / Borland style | ||||||
| @@ -395,19 +395,22 @@ CROSS COMPILE | |||||||
| PORTS | PORTS | ||||||
| ===== | ===== | ||||||
|    This is a probably incomplete list of known hardware and operating systems |    This is a probably incomplete list of known hardware and operating systems | ||||||
|    that curl has been compiled for. If you know one system curl compiles and |    that curl has been compiled for. If you know a system curl compiles and | ||||||
|    runs on, that isn't listed, please let us know! |    runs on, that isn't listed, please let us know! | ||||||
|  |  | ||||||
|         - Alpha DEC OSF 4 |         - Alpha DEC OSF 4 | ||||||
|         - Alpha Digital UNIX v3.2 |         - Alpha Digital UNIX v3.2 | ||||||
|         - Alpha FreeBSD 4.1 |         - Alpha FreeBSD 4.1, 4.5 | ||||||
|         - Alpha Linux 2.2.16 |         - Alpha Linux 2.2, 2.4 | ||||||
|  |         - Alpha NetBSD 1.5.2 | ||||||
|  |         - Alpha OpenBSD 3.0 | ||||||
|         - Alpha OpenVMS V7.1-1H2 |         - Alpha OpenVMS V7.1-1H2 | ||||||
|         - Alpha Tru64 v5.0 5.1 |         - Alpha Tru64 v5.0 5.1 | ||||||
|         - HP-PA HP-UX 9.X 10.X 11.X |         - HP-PA HP-UX 9.X 10.X 11.X | ||||||
|         - HP-PA Linux |         - HP-PA Linux | ||||||
|         - MIPS IRIX 6.2, 6.5 |         - MIPS IRIX 6.2, 6.5 | ||||||
|         - MIPS Linux |         - MIPS Linux | ||||||
|  |         - Pocket PC/Win CE 3.0 | ||||||
|         - Power AIX 4.2, 4.3.1, 4.3.2 |         - Power AIX 4.2, 4.3.1, 4.3.2 | ||||||
|         - PowerPC Darwin 1.0 |         - PowerPC Darwin 1.0 | ||||||
|         - PowerPC Linux |         - PowerPC Linux | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ Windows vs Unix | |||||||
|  Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All |  Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All | ||||||
|  conditionals that deal with features *should* instead be in the format |  conditionals that deal with features *should* instead be in the format | ||||||
|  '#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts, |  '#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts, | ||||||
|  we maintain two config-win32.h files (one in / and one in src/) that are |  we maintain two config-win32.h files (one in lib/ and one in src/) that are | ||||||
|  supposed to look exactly as a config.h file would have looked like on a |  supposed to look exactly as a config.h file would have looked like on a | ||||||
|  Windows machine! |  Windows machine! | ||||||
|  |  | ||||||
| @@ -69,10 +69,10 @@ Library | |||||||
|  rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are |  rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are | ||||||
|  put in the lib/easy.c file. |  put in the lib/easy.c file. | ||||||
|  |  | ||||||
|  Starting with libcurl 7.8, curl_global_init_() and curl_global_cleanup() were |  curl_global_init_() and curl_global_cleanup() should be called by the | ||||||
|  introduced. They should be called by the application to initialize and clean |  application to initialize and clean up global stuff in the library. As of | ||||||
|  up global stuff in the library. As of today, they just do the global SSL |  today, it can handle the global SSL initing if SSL is enabled and it can init | ||||||
|  initing if SSL is enabled. libcurl itself has no "global" scope. |  the socket layer on windows machines. libcurl itself has no "global" scope. | ||||||
|  |  | ||||||
|  All printf()-style functions use the supplied clones in lib/mprintf.c. This |  All printf()-style functions use the supplied clones in lib/mprintf.c. This | ||||||
|  makes sure we stay absolutely platform independent. |  makes sure we stay absolutely platform independent. | ||||||
|   | |||||||
							
								
								
									
										73
									
								
								docs/KNOWN_BUGS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								docs/KNOWN_BUGS
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | These are problems known to exist at the time of this release. Feel free to | ||||||
|  | join in and help us correct one or more of these! Also be sure to check the | ||||||
|  | changelog of the current development status, as one or more of these problems | ||||||
|  | may have been fixed since this was written! | ||||||
|  |  | ||||||
|  | * Running 'make test' on Mac OS X gives 4 errors. This seems to be related | ||||||
|  |   to some kind of libtool problem: | ||||||
|  |   http://curl.haxx.se/mail/archive-2002-03/0029.html and | ||||||
|  |   http://curl.haxx.se/mail/archive-2002-03/0033.html | ||||||
|  |  | ||||||
|  | * libcurl does not deal nicely with files larger than 2GB | ||||||
|  |  | ||||||
|  | * GOPHER transfers seem broken | ||||||
|  |  | ||||||
|  | ------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | Q: My program blows up when I run lots of curl_easy_perform() calls on a | ||||||
|  | single thread | ||||||
|  | Q: My program dies when a single thread re-enters the win32 select() call | ||||||
|  | via curl_easy_perform() | ||||||
|  | Q: --- add your own flavour here --- | ||||||
|  |  | ||||||
|  | Single Threaded Re-Entracy | ||||||
|  | -------------------------- | ||||||
|  |  | ||||||
|  | There is a glitch / trick to using cURL on Win32 related to re-entrancy. | ||||||
|  | This experience was gained on verion 7.9.4 using Windows NT SP3 in a banking | ||||||
|  | environment (just in case you wanted to know). | ||||||
|  |  | ||||||
|  | If you have already called curl_easy_perform(), and *somehow* you cause your | ||||||
|  | single thread of execution to make another call to curl_easy_perform() - the | ||||||
|  | windows socket() call used to create a new socket for the second connection | ||||||
|  | can return with 10044 / 10043 error codes. | ||||||
|  |  | ||||||
|  | The WSA errors we experienced are: | ||||||
|  | WSAEPROTONOSUPPORT  | ||||||
|  | (10043)  | ||||||
|  | Protocol not supported.  | ||||||
|  | The requested protocol has not been configured into the system, or no | ||||||
|  | implementation for it exists. For example, a socket call requests a | ||||||
|  | SOCK_DGRAM socket, but specifies a stream protocol.  | ||||||
|  |  | ||||||
|  | WSAESOCKTNOSUPPORT  | ||||||
|  | (10044)  | ||||||
|  | Socket type not supported.  | ||||||
|  | The support for the specified socket type does not exist in this address | ||||||
|  | family. For example, the optional type SOCK_RAW might be selected in a | ||||||
|  | socket call, and the implementation does not support SOCK_RAW sockets at | ||||||
|  | all.  | ||||||
|  |  | ||||||
|  | We have experienced this by creating a timer that ticks every 20ms, and on | ||||||
|  | the tick making a curl_easy_perform() call.  The call usually completed in | ||||||
|  | about 300ms.  And we expected (before this test) that the timer would NOT be | ||||||
|  | fired during a call to curl_easy_perform(), howvever, while the first | ||||||
|  | curl_easy_perform() is running a tick *is* fired by the windows API somehow, | ||||||
|  | and we then call curl_easy_perform() again - thus single threaded | ||||||
|  | re-entrancy is achieved. | ||||||
|  |  | ||||||
|  | Notes: | ||||||
|  | * We made sure that a new CURL structure was being used for each | ||||||
|  | curl_easy_perform() request, and that the curl_global_init() had been called | ||||||
|  | beforehand.   | ||||||
|  | * I'm happy to answer any questions about this problem to try to track it | ||||||
|  | down. | ||||||
|  | * Once the socket() call started failing, there is no hope - it never works | ||||||
|  | again. | ||||||
|  | * Slowing the timer down to give each request enough time to complete solves | ||||||
|  | this problem completely. | ||||||
|  |  | ||||||
|  | If anyone has the source code to the WinNT implementation of socket() and | ||||||
|  | can figure out WHY this can occur, more tracing can be performed. | ||||||
|  |  | ||||||
|  |         John Clayton <John.Clayton at barclayscapital.com> | ||||||
							
								
								
									
										58
									
								
								docs/MANUAL
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								docs/MANUAL
									
									
									
									
									
								
							| @@ -246,25 +246,25 @@ POST (HTTP) | |||||||
|   -F accepts parameters like -F "name=contents". If you want the contents to |   -F accepts parameters like -F "name=contents". If you want the contents to | ||||||
|   be read from a file, use <@filename> as contents. When specifying a file, |   be read from a file, use <@filename> as contents. When specifying a file, | ||||||
|   you can also specify the file content type by appending ';type=<mime type>' |   you can also specify the file content type by appending ';type=<mime type>' | ||||||
|   to the file name. You can also post the contents of several files in one field. |   to the file name. You can also post the contents of several files in one | ||||||
|   For example, the field name 'coolfiles' is used to send three  files, with |   field.  For example, the field name 'coolfiles' is used to send three files, | ||||||
|   different content types using the following syntax: |   with different content types using the following syntax: | ||||||
|  |  | ||||||
|         curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \ |         curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \ | ||||||
|         http://www.post.com/postit.cgi |         http://www.post.com/postit.cgi | ||||||
|  |  | ||||||
|   If the content-type is not specified, curl will try to guess from the file |   If the content-type is not specified, curl will try to guess from the file | ||||||
|   extension  (it only knows a few), or use the previously specified type |   extension (it only knows a few), or use the previously specified type (from | ||||||
|   (from an earlier file if several files are specified in a list) or else it |   an earlier file if several files are specified in a list) or else it will | ||||||
|   will  using the default type 'text/plain'. |   using the default type 'text/plain'. | ||||||
|  |  | ||||||
|   Emulate a fill-in form with -F. Let's say you fill in three fields in a |   Emulate a fill-in form with -F. Let's say you fill in three fields in a | ||||||
|   form. One field is a file name which to post, one field is your name and one |   form. One field is a file name which to post, one field is your name and one | ||||||
|   field is a file description. We want to post the file we have written named |   field is a file description. We want to post the file we have written named | ||||||
|   "cooltext.txt". To let curl do the posting of this data instead of your |   "cooltext.txt". To let curl do the posting of this data instead of your | ||||||
|   favourite browser, you have to read the HTML source of the form page and find |   favourite browser, you have to read the HTML source of the form page and | ||||||
|   the names of the input fields. In our example, the input field names are |   find the names of the input fields. In our example, the input field names | ||||||
|   'file', 'yourname' and 'filedescription'. |   are 'file', 'yourname' and 'filedescription'. | ||||||
|  |  | ||||||
|         curl -F "file=@cooltext.txt" -F "yourname=Daniel" \ |         curl -F "file=@cooltext.txt" -F "yourname=Daniel" \ | ||||||
|              -F "filedescription=Cool text file with cool text inside" \ |              -F "filedescription=Cool text file with cool text inside" \ | ||||||
| @@ -689,7 +689,7 @@ ENVIRONMENT VARIABLES | |||||||
|  |  | ||||||
|   Curl reads and understands the following environment variables: |   Curl reads and understands the following environment variables: | ||||||
|  |  | ||||||
|         HTTP_PROXY, HTTPS_PROXY, FTP_PROXY, GOPHER_PROXY |         http_proxy, HTTPS_PROXY, FTP_PROXY, GOPHER_PROXY | ||||||
|  |  | ||||||
|   They should be set for protocol-specific proxies. General proxy should be |   They should be set for protocol-specific proxies. General proxy should be | ||||||
|   set with |   set with | ||||||
| @@ -800,19 +800,39 @@ PERSISTANT CONNECTIONS | |||||||
| MAILING LISTS | MAILING LISTS | ||||||
|  |  | ||||||
|   For your convenience, we have several open mailing lists to discuss curl, |   For your convenience, we have several open mailing lists to discuss curl, | ||||||
|   its development and things relevant to this. |   its development and things relevant to this. Get all info at | ||||||
|  |   http://curl.haxx.se/mail/. The lists available are: | ||||||
|  |  | ||||||
|   To subscribe to the main curl list, mail curl-request@contactor.se with |   curl-users | ||||||
|   "subscribe <fill in your email address>" in the body. |  | ||||||
|  |  | ||||||
|   To subscribe to the curl-library users/deverlopers list, follow the |     Users of the command line tool. How to use it, what doesn't work, new | ||||||
|   instructions at http://curl.haxx.se/mail/ |     features, related tools, questions, news, installations, compilations, | ||||||
|  |     running, porting etc. | ||||||
|  |  | ||||||
|   To subscribe to the curl-announce list, to only get information about new |   curl-library | ||||||
|   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 |     Developers using or developing libcurl. Bugs, extensions, improvements. | ||||||
|   discussed, follow the instructions at http://curl.haxx.se/mail/ |  | ||||||
|  |   curl-announce | ||||||
|  |  | ||||||
|  |     Low-traffic. Only announcements of new public versions. | ||||||
|  |  | ||||||
|  |   curl-and-PHP | ||||||
|  |  | ||||||
|  |     Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP | ||||||
|  |     with a curl angle. | ||||||
|  |  | ||||||
|  |   curl-commits | ||||||
|  |  | ||||||
|  |     Receives notifications on all CVS commits done to the curl source module. | ||||||
|  |     This can become quite a large amount of mails during intense development, | ||||||
|  |     be aware. This is for us who liks email... | ||||||
|  |  | ||||||
|  |   curl-www-commits | ||||||
|  |  | ||||||
|  |     Receives notifications on all CVS commits done to the curl www module | ||||||
|  |     (basicly the web site).  This can become quite a large amount of mails | ||||||
|  |     during intense changing, be aware. This is for us who liks email... | ||||||
|  |  | ||||||
|   Please direct curl questions, feature requests and trouble reports to one of |   Please direct curl questions, feature requests and trouble reports to one of | ||||||
|   these mailing lists instead of mailing any individual. |   these mailing lists instead of mailing any individual. | ||||||
|   | |||||||
| @@ -6,69 +6,24 @@ AUTOMAKE_OPTIONS = foreign no-dependencies | |||||||
|  |  | ||||||
| man_MANS = \ | man_MANS = \ | ||||||
| 	curl.1 \ | 	curl.1 \ | ||||||
| 	curl-config.1 \ | 	curl-config.1 | ||||||
| 	curl_easy_cleanup.3 \ |  | ||||||
| 	curl_easy_getinfo.3 \ |  | ||||||
| 	curl_easy_init.3 \ |  | ||||||
| 	curl_easy_perform.3 \ |  | ||||||
| 	curl_easy_setopt.3 \ |  | ||||||
| 	curl_easy_duphandle.3 \ |  | ||||||
| 	curl_formparse.3 \ |  | ||||||
| 	curl_formadd.3 \ |  | ||||||
| 	curl_formfree.3 \ |  | ||||||
| 	curl_getdate.3 \ |  | ||||||
| 	curl_getenv.3 \ |  | ||||||
| 	curl_slist_append.3 \ |  | ||||||
| 	curl_slist_free_all.3 \ |  | ||||||
| 	curl_version.3 \ |  | ||||||
| 	curl_escape.3 \ |  | ||||||
| 	curl_unescape.3 \ |  | ||||||
| 	curl_strequal.3 \ |  | ||||||
| 	curl_strnequal.3 \ |  | ||||||
| 	curl_mprintf.3 \ |  | ||||||
| 	curl_global_init.3 \ |  | ||||||
| 	curl_global_cleanup.3 \ |  | ||||||
| 	libcurl.3 |  | ||||||
|  |  | ||||||
| SUBDIRS = examples |  | ||||||
|  |  | ||||||
| HTMLPAGES = \ | HTMLPAGES = \ | ||||||
| 	curl.html \ | 	curl.html \ | ||||||
| 	curl-config.html \ | 	curl-config.html | ||||||
| 	curl_easy_cleanup.html \ |  | ||||||
| 	curl_easy_getinfo.html \ |  | ||||||
| 	curl_easy_init.html \ |  | ||||||
| 	curl_easy_perform.html \ |  | ||||||
| 	curl_easy_setopt.html \ |  | ||||||
| 	curl_easy_duphandle.html \ |  | ||||||
| 	curl_formadd.html \ |  | ||||||
| 	curl_formparse.html \ |  | ||||||
| 	curl_formfree.html \ |  | ||||||
| 	curl_getdate.html \ |  | ||||||
| 	curl_getenv.html \ |  | ||||||
| 	curl_slist_append.html \ |  | ||||||
| 	curl_slist_free_all.html \ |  | ||||||
| 	curl_version.html \ |  | ||||||
| 	curl_escape.html \ |  | ||||||
| 	curl_unescape.html \ |  | ||||||
| 	curl_strequal.html \ |  | ||||||
| 	curl_strnequal.html \ |  | ||||||
| 	curl_mprintf.html \ |  | ||||||
| 	curl_global_init.html \ |  | ||||||
| 	curl_global_cleanup.html \ |  | ||||||
| 	libcurl.html \ |  | ||||||
| 	index.html |  | ||||||
|  |  | ||||||
| EXTRA_DIST = $(man_MANS) \ | SUBDIRS = examples libcurl | ||||||
| 	MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \ |  | ||||||
| 	README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS \ | EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS		\ | ||||||
| 	VERSIONS $(HTMLPAGES) | 	     README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS	\ | ||||||
|  | 	     VERSIONS KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) | ||||||
|  |  | ||||||
| MAN2HTML= gnroff -man $< | man2html >$@ | MAN2HTML= gnroff -man $< | man2html >$@ | ||||||
|  |  | ||||||
| SUFFIXES = .1 .3 .html | SUFFIXES = .1 .3 .html | ||||||
|  |  | ||||||
| html: $(HTMLPAGES) | html: $(HTMLPAGES) | ||||||
|  | 	cd libcurl; make html | ||||||
|  |  | ||||||
| .3.html: | .3.html: | ||||||
| 	$(MAN2HTML) | 	$(MAN2HTML) | ||||||
|   | |||||||
| @@ -5,10 +5,9 @@ | |||||||
|                              \___|\___/|_| \_\_____| |                              \___|\___/|_| \_\_____| | ||||||
|  |  | ||||||
|  |  | ||||||
| This document has been introduced in order to let you find documents that | This document lists documents that specify standards used by curl, software | ||||||
| specify standards used by curl, software that extends curl, web pages with | that extends curl, web pages with similar utilities and information pages that | ||||||
| "competing" utilities and information pages that describe some of the tools | describe some of the tools that we use to build/compile/develop curl. | ||||||
| that we use to build/compile/develop curl. |  | ||||||
|  |  | ||||||
| Standards | Standards | ||||||
| --------- | --------- | ||||||
|   | |||||||
| @@ -79,3 +79,5 @@ that have contributed with non-trivial parts: | |||||||
|  - Eric Lavigne <erlavigne@wanadoo.fr> |  - Eric Lavigne <erlavigne@wanadoo.fr> | ||||||
|  - Marcus Webster <marcus.webster@phocis.com> |  - Marcus Webster <marcus.webster@phocis.com> | ||||||
|  - G<>tz Babin-Ebell <babin<69>ebell@trustcenter.de> |  - G<>tz Babin-Ebell <babin<69>ebell@trustcenter.de> | ||||||
|  |  - Andreas Damm <andreas-sourceforge@radab.org> | ||||||
|  |  - Jacky Lam <sylam@emsoftltd.com> | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								docs/TODO
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								docs/TODO
									
									
									
									
									
								
							| @@ -17,9 +17,7 @@ TODO | |||||||
|  |  | ||||||
|  * Make content encoding/decoding internally be made using a filter system. |  * Make content encoding/decoding internally be made using a filter system. | ||||||
|  |  | ||||||
|  * The new 'multi' interface is being designed. Work out the details, start |  * Test the 'multi' interface more. | ||||||
|    implementing and write test applications! |  | ||||||
|    [http://curl.haxx.se/lxr/source/lib/multi.h] |  | ||||||
|  |  | ||||||
|  * Introduce another callback interface for upload/download that makes one |  * Introduce another callback interface for upload/download that makes one | ||||||
|    less copy of data and thus a faster operation. |    less copy of data and thus a faster operation. | ||||||
| @@ -34,12 +32,14 @@ TODO | |||||||
|    otherwise it isn't really interesting. |    otherwise it isn't really interesting. | ||||||
|  |  | ||||||
|  * Data sharing. Tell which easy handles within a multi handle that should |  * Data sharing. Tell which easy handles within a multi handle that should | ||||||
|    share cookies, connection cache, dns cache, ssl session cache. |    share cookies, connection cache, dns cache, ssl session cache.  Full | ||||||
|  |    suggestion found here: http://curl.haxx.se/dev/sharing.txt | ||||||
|  |  | ||||||
|  * Mutexes. By adding mutex callback support, the 'data sharing' mentioned |  * Mutexes. By adding mutex callback support, the 'data sharing' mentioned | ||||||
|    above can be made between several easy handles running in different threads |    above can be made between several easy handles running in different threads | ||||||
|    too. The actual mutex implementations will be left for the application to |    too. The actual mutex implementations will be left for the application to | ||||||
|    implement, libcurl will merely call 'getmutex' and 'leavemutex' callbacks. |    implement, libcurl will merely call 'getmutex' and 'leavemutex' callbacks. | ||||||
|  |    Part of the sharing suggestion at: http://curl.haxx.se/dev/sharing.txt | ||||||
|  |  | ||||||
|  * No-faster-then-this transfers. Many people have limited bandwidth and they |  * No-faster-then-this transfers. Many people have limited bandwidth and they | ||||||
|    want the ability to make sure their transfers never use more bandwith than |    want the ability to make sure their transfers never use more bandwith than | ||||||
| @@ -53,13 +53,14 @@ TODO | |||||||
|    especially regular HTTP POST), the FTP command sending etc. |    especially regular HTTP POST), the FTP command sending etc. | ||||||
|  |  | ||||||
|  * Go through the code and verify that libcurl deals with big files >2GB and |  * Go through the code and verify that libcurl deals with big files >2GB and | ||||||
|    >4GB all over. Bug reports indicate that it doesn't currently work |    >4GB all over. Bug reports (and source reviews) indicate that it doesn't | ||||||
|    properly. |    currently work properly. | ||||||
|  |  | ||||||
|  |  * Make the built-in progress meter use its own dedicated output stream, and | ||||||
|  |    make it possible to set it. Use stderr by default. | ||||||
|  |  | ||||||
|  DOCUMENTATION |  DOCUMENTATION | ||||||
|  |  | ||||||
|  * Document all CURLcode error codes, why they happen and what most likely |  | ||||||
|    will make them not happen again. In a libcurl point of view. |  | ||||||
|  |  | ||||||
|  FTP |  FTP | ||||||
|  |  | ||||||
| @@ -74,7 +75,9 @@ TODO | |||||||
|    already working http dito works. It of course requires that 'MDTM' works, |    already working http dito works. It of course requires that 'MDTM' works, | ||||||
|    and it isn't a standard FTP command. |    and it isn't a standard FTP command. | ||||||
|  |  | ||||||
|  * Add FTPS support with SSL for the data connection too. |  * Add FTPS support with SSL for the data connection too.  This should be made | ||||||
|  |    according to the specs written in draft-murray-auth-ftp-ssl-08.txt, | ||||||
|  |    "Securing FTP with TLS" | ||||||
|  |  | ||||||
|  HTTP |  HTTP | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								docs/curl.1
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								docs/curl.1
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | |||||||
| .\" nroff -man curl.1 | .\" nroff -man curl.1 | ||||||
| .\" Written by Daniel Stenberg | .\" Written by Daniel Stenberg | ||||||
| .\" | .\" | ||||||
| .TH curl 1 "30 Nov 2001" "Curl 7.9.2" "Curl Manual" | .TH curl 1 "7 May 2002" "Curl 7.9.7" "Curl Manual" | ||||||
| .SH NAME | .SH NAME | ||||||
| curl \- transfer a URL | curl \- transfer a URL | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| @@ -99,10 +99,7 @@ If this option is used severl times, the last one will override the others. | |||||||
| .IP "--connect-timeout <seconds>" | .IP "--connect-timeout <seconds>" | ||||||
| Maximum time in seconds that you allow the connection to the server to take. | Maximum time in seconds that you allow the connection to the server to take. | ||||||
| This only limits the connection phase, once curl has connected this option is | This only limits the connection phase, once curl has connected this option is | ||||||
| of no more use. This option didn't work in win32 systems until 7.7.2.  See | of no more use. See also the \fI--max-time\fP option. | ||||||
| also the |  | ||||||
| .I "--max-time" |  | ||||||
| option. |  | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
| .IP "-c/--cookie-jar <file name>" | .IP "-c/--cookie-jar <file name>" | ||||||
| @@ -125,6 +122,10 @@ Use "-C -" to tell curl to automatically find out where/how to resume the | |||||||
| transfer. It then uses the given output/input files to figure that out. | transfer. It then uses the given output/input files to figure that out. | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
|  | .IP "--crlf" | ||||||
|  | (FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390). | ||||||
|  |  | ||||||
|  | If this option is used twice, the second will again disable crlf converting. | ||||||
| .IP "-d/--data <data>" | .IP "-d/--data <data>" | ||||||
| (HTTP) Sends the specified data in a POST request to the HTTP server, in a way | (HTTP) Sends the specified data in a POST request to the HTTP server, in a way | ||||||
| that can emulate as if a user has filled in a HTML form and pressed the submit | that can emulate as if a user has filled in a HTML form and pressed the submit | ||||||
| @@ -167,16 +168,17 @@ append data. | |||||||
| downloads. Curl will normally always first attempt to use EPSV before PASV, | downloads. Curl will normally always first attempt to use EPSV before PASV, | ||||||
| but with this option, it will not try using EPSV. | but with this option, it will not try using EPSV. | ||||||
|  |  | ||||||
| IF this option is used several times, each occurrence will toggle this on/off. | If this option is used several times, each occurrence will toggle this on/off. | ||||||
| .IP "-D/--dump-header <file>" | .IP "-D/--dump-header <file>" | ||||||
| (HTTP/FTP) | Write the protocol headers to the specified file. | ||||||
| Write the HTTP headers to this file. Write the FTP file info to this |  | ||||||
| file if -I/--head is used. |  | ||||||
|  |  | ||||||
| This option is handy to use when you want to store the cookies that a HTTP | This option is handy to use when you want to store the cookies that a HTTP | ||||||
| site sends to you. The cookies could then be read in a second curl invoke by | site sends to you. The cookies could then be read in a second curl invoke by | ||||||
| using the -b/--cookie option! | using the -b/--cookie option! | ||||||
|  |  | ||||||
|  | When used on FTP, the ftp server response lines are considered being "headers" | ||||||
|  | and thus are saved there. | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
| .IP "-e/--referer <URL>" | .IP "-e/--referer <URL>" | ||||||
| (HTTP) Sends the "Referer Page" information to the HTTP server. This can also | (HTTP) Sends the "Referer Page" information to the HTTP server. This can also | ||||||
| @@ -187,6 +189,12 @@ previous URL when it follows a Location: header. The ";auto" string can be | |||||||
| used alone, even if you don't set an initial referer. | used alone, even if you don't set an initial referer. | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
|  | .IP "--environment" | ||||||
|  | (RISC OS ONLY) Sets a range of environment variables, using the names the -w | ||||||
|  | option supports, to easier allow extraction of useful information after having | ||||||
|  | run curl. | ||||||
|  |  | ||||||
|  | If this option is used several times, each occurrence will toggle this on/off. | ||||||
| .IP "--egd-file <file>" | .IP "--egd-file <file>" | ||||||
| (HTTPS) Specify the path name to the Entropy Gathering Daemon socket. The | (HTTPS) Specify the path name to the Entropy Gathering Daemon socket. The | ||||||
| socket is used to seed the random engine for SSL connections. See also the | socket is used to seed the random engine for SSL connections. See also the | ||||||
| @@ -207,13 +215,11 @@ peer. The certificate must be in PEM format. | |||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
| .IP "-f/--fail" | .IP "-f/--fail" | ||||||
| (HTTP) | (HTTP) Fail silently (no output at all) on server errors. This is mostly done | ||||||
| Fail silently (no output at all) on server errors. This is mostly done | like this to better enable scripts etc to better deal with failed attempts. In | ||||||
| like this to better enable scripts etc to better deal with failed | normal cases when a HTTP server fails to deliver a document, it returns a HTML | ||||||
| attempts. In normal cases when a HTTP server fails to deliver a | document stating so (which often also describes why and more). This flag will | ||||||
| document, it returns a HTML document stating so (which often also | prevent curl from outputting that and fail silently instead. | ||||||
| describes why and more). This flag will prevent curl from |  | ||||||
| outputting that and fail silently instead. |  | ||||||
|  |  | ||||||
| If this option is used twice, the second will again disable silent failure. | If this option is used twice, the second will again disable silent failure. | ||||||
| .IP "-F/--form <name=content>" | .IP "-F/--form <name=content>" | ||||||
| @@ -241,13 +247,17 @@ This option can be used multiple times. | |||||||
| This option switches off the "URL globbing parser". When you set this option, | 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 | 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 | 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 | contents but they should be encoded according to the URI standard. | ||||||
| added in curl 7.6) |  | ||||||
| .IP "-G/--get" | .IP "-G/--get" | ||||||
| When used, this option will make all data specified with -d/--data or | When used, this option will make all data specified with -d/--data or | ||||||
| --data-binary to be used in a HTTP GET request instead of the POST request | --data-binary to be used in a HTTP GET request instead of the POST request | ||||||
| that otherwise would be used. The data will be appended to the URL with a '?' | that otherwise would be used. The data will be appended to the URL with a '?' | ||||||
| separator. (Option added in curl 7.9) | separator. (Option added in curl 7.9) | ||||||
|  |  | ||||||
|  | If used in combination with -I, the POST data will instead be appended to the | ||||||
|  | URL with a HEAD request. | ||||||
|  |  | ||||||
|  | If used multiple times, nothing special happens. | ||||||
| .IP "-h/--help" | .IP "-h/--help" | ||||||
| Usage help. | Usage help. | ||||||
| .IP "-H/--header <header>" | .IP "-H/--header <header>" | ||||||
| @@ -260,7 +270,7 @@ set headers without knowing perfectly well what you're doing. Replacing an | |||||||
| internal header with one without content on the right side of the colon will | internal header with one without content on the right side of the colon will | ||||||
| prevent that header from appearing. | prevent that header from appearing. | ||||||
|  |  | ||||||
| This option can be used multiple times. | This option can be used multiple times to add/replace/remove multiple headers. | ||||||
| .IP "-i/--include" | .IP "-i/--include" | ||||||
| (HTTP) | (HTTP) | ||||||
| Include the HTTP-header in the output. The HTTP-header includes things | Include the HTTP-header in the output. The HTTP-header includes things | ||||||
| @@ -281,6 +291,13 @@ which this uses to get nothing but the header of a document. When used | |||||||
| on a FTP file, curl displays the file size only. | on a FTP file, curl displays the file size only. | ||||||
|  |  | ||||||
| If this option is used twice, the second will again disable header only. | If this option is used twice, the second will again disable header only. | ||||||
|  | .IP "-j/--junk-session-cookies" | ||||||
|  | (HTTP) When curl is told to read cookies from a given file, this option will | ||||||
|  | make it discard all "session cookies". This will basicly have the same effect | ||||||
|  | as if a new session is started. Typical browsers always discard session | ||||||
|  | cookies when they're closed down. (Added in 7.9.7) | ||||||
|  |  | ||||||
|  | If this option is used several times, each occurrence will toggle this on/off. | ||||||
| .IP "--krb4 <level>" | .IP "--krb4 <level>" | ||||||
| (FTP) Enable kerberos4 authentication and use. The level must be entered and | (FTP) Enable kerberos4 authentication and use. The level must be entered and | ||||||
| should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use | should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use | ||||||
| @@ -298,6 +315,12 @@ treated as a comment. | |||||||
|  |  | ||||||
| Specify the filename as '-' to make curl read the file from stdin. | Specify the filename as '-' to make curl read the file from stdin. | ||||||
|  |  | ||||||
|  | Note that to be able to specify a URL in the config file, you need to specify | ||||||
|  | it using the --url option, and not by simply writing the URL on its own | ||||||
|  | line. So, it could look similar to this: | ||||||
|  |  | ||||||
|  | url = "http://curl.haxx.se/docs/" | ||||||
|  |  | ||||||
| This option can be used multiple times. | This option can be used multiple times. | ||||||
| .IP "-l/--list-only" | .IP "-l/--list-only" | ||||||
| (FTP) | (FTP) | ||||||
| @@ -319,10 +342,8 @@ If this option is used twice, the second will again disable location following. | |||||||
| .IP "-m/--max-time <seconds>" | .IP "-m/--max-time <seconds>" | ||||||
| Maximum time in seconds that you allow the whole operation to take.  This is | Maximum time in seconds that you allow the whole operation to take.  This is | ||||||
| useful for preventing your batch jobs from hanging for hours due to slow | useful for preventing your batch jobs from hanging for hours due to slow | ||||||
| networks or links going down.  This doesn't work fully in win32 systems. | networks or links going down.  This doesn't work fully in win32 systems.  See | ||||||
| See also the | also the \fI--connect-timeout\fP option. | ||||||
| .I "--connect-timeout" |  | ||||||
| option. |  | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
| .IP "-M/--manual" | .IP "-M/--manual" | ||||||
| @@ -479,6 +500,12 @@ 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. | 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. | If this option is used twice, the second will again disable show error. | ||||||
|  | .IP "--stderr <file>" | ||||||
|  | Redirect all writes to stderr to the specified file instead. If the file name | ||||||
|  | is a plain '-', it is instead written to stdout. This option has no point when | ||||||
|  | you're using a shell with decent redirecting capabilities. | ||||||
|  |  | ||||||
|  | If this option is used several times, the last one will be used. | ||||||
| .IP "-t/--telnet-option <OPT=val>" | .IP "-t/--telnet-option <OPT=val>" | ||||||
| Pass options to the telnet protocol. Supported options are: | Pass options to the telnet protocol. Supported options are: | ||||||
|  |  | ||||||
| @@ -498,6 +525,24 @@ this is used on a http(s) server, the PUT command will be used. | |||||||
| Use the file name "-" (a single dash) to use stdin instead of a given file. | Use the file name "-" (a single dash) to use stdin instead of a given file. | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
|  | .IP "--trace <file>" | ||||||
|  | Enables a full trace dump of all incoming and outgoing data, including | ||||||
|  | descriptive information, to the given output file. Use "-" as filename to have | ||||||
|  | the output sent to stdout. | ||||||
|  |  | ||||||
|  | If this option is used several times, the last one will be used. (Added in | ||||||
|  | curl 7.9.7) | ||||||
|  | .IP "--trace-ascii <file>" | ||||||
|  | Enables a full trace dump of all incoming and outgoing data, including | ||||||
|  | descriptive information, to the given output file. Use "-" as filename to have | ||||||
|  | the output sent to stdout. | ||||||
|  |  | ||||||
|  | This is very similar to --trace, but leaves out the hex part and only shows | ||||||
|  | the ASCII part of the dump. It makes smaller output that might be easier to | ||||||
|  | read for untrained humans. | ||||||
|  |  | ||||||
|  | If this option is used several times, the last one will be used. (Added in | ||||||
|  | curl 7.9.7) | ||||||
| .IP "-u/--user <user:password>" | .IP "-u/--user <user:password>" | ||||||
| Specify user and password to use when fetching. See README.curl for detailed | Specify user and password to use when fetching. See README.curl for detailed | ||||||
| examples of how to use this. If no password is specified, curl will | examples of how to use this. If no password is specified, curl will | ||||||
| @@ -594,6 +639,9 @@ The average download speed that curl measured for the complete download. | |||||||
| .TP | .TP | ||||||
| .B speed_upload | .B speed_upload | ||||||
| The average upload speed that curl measured for the complete upload. | The average upload speed that curl measured for the complete upload. | ||||||
|  | .TP | ||||||
|  | .B content_type | ||||||
|  | The Content-Type of the requested document, if there was any. (Added in 7.9.5) | ||||||
| .RE | .RE | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
| @@ -645,6 +693,12 @@ Start the date expression with a dash (-) to make it request for a document | |||||||
| that is older than the given date/time, default is a document that is newer | that is older than the given date/time, default is a document that is newer | ||||||
| than the specified date/time. | than the specified date/time. | ||||||
|  |  | ||||||
|  | If this option is used several times, the last one will be used. | ||||||
|  | .IP "-Z/--max-redirs <num>" | ||||||
|  | Set maximum number of redirection-followings allowed. If -L/--location is | ||||||
|  | used, this option can be used to prevent curl from following redirections "in | ||||||
|  | absurdum". | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. | If this option is used several times, the last one will be used. | ||||||
| .IP "-3/--sslv3" | .IP "-3/--sslv3" | ||||||
| (HTTPS) | (HTTPS) | ||||||
| @@ -660,16 +714,6 @@ Make curl display progress information as a progress bar instead of the | |||||||
| default statistics. | default statistics. | ||||||
|  |  | ||||||
| If this option is used twice, the second will again disable the progress bar. | If this option is used twice, the second will again disable the progress bar. | ||||||
| .IP "--crlf" |  | ||||||
| (FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390). |  | ||||||
|  |  | ||||||
| If this option is used twice, the second will again disable crlf converting. |  | ||||||
| .IP "--stderr <file>" |  | ||||||
| Redirect all writes to stderr to the specified file instead. If the file name |  | ||||||
| is a plain '-', it is instead written to stdout. This option has no point when |  | ||||||
| you're using a shell with decent redirecting capabilities. |  | ||||||
|  |  | ||||||
| If this option is used several times, the last one will be used. |  | ||||||
| .SH FILES | .SH FILES | ||||||
| .I ~/.curlrc | .I ~/.curlrc | ||||||
| .RS | .RS | ||||||
|   | |||||||
| @@ -1,29 +0,0 @@ | |||||||
| .\" You can view this file with: |  | ||||||
| .\" nroff -man [file] |  | ||||||
| .\" $Id$ |  | ||||||
| .\" |  | ||||||
| .TH curl_easy_cleanup 3 "5 March 2001" "libcurl 7.7" "libcurl Manual" |  | ||||||
| .SH NAME |  | ||||||
| curl_easy_cleanup - End a libcurl session |  | ||||||
| .SH SYNOPSIS |  | ||||||
| .B #include <curl/curl.h> |  | ||||||
| .sp |  | ||||||
| .BI "void curl_easy_cleanup(CURL *" handle ");" |  | ||||||
| .ad |  | ||||||
| .SH DESCRIPTION |  | ||||||
| This function must be the last function to call for a curl session. It is the |  | ||||||
| opposite of the |  | ||||||
| .I curl_easy_init |  | ||||||
| function and must be called with the same |  | ||||||
| .I handle |  | ||||||
| as input as the curl_easy_init call returned. |  | ||||||
|  |  | ||||||
| This will effectively close all connections libcurl has been used and possibly |  | ||||||
| has kept open until now. Don't call this function if you intend to transfer |  | ||||||
| more files (libcurl 7.7 or later). |  | ||||||
| .SH RETURN VALUE |  | ||||||
| None |  | ||||||
| .SH "SEE ALSO" |  | ||||||
| .BR curl_easy_init "(3), " |  | ||||||
| .SH BUGS |  | ||||||
| Surely there are some, you tell me! |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| .\" You can view this file with: |  | ||||||
| .\" nroff -man [file] |  | ||||||
| .\" $Id$ |  | ||||||
| .\" |  | ||||||
| .TH curl_easy_init 3 "14 August 2001" "libcurl 7.8.1" "libcurl Manual" |  | ||||||
| .SH NAME |  | ||||||
| curl_easy_init - Start a libcurl session |  | ||||||
| .SH SYNOPSIS |  | ||||||
| .B #include <curl/curl.h> |  | ||||||
| .sp |  | ||||||
| .BI "CURL *curl_easy_init( );" |  | ||||||
| .ad |  | ||||||
| .SH DESCRIPTION |  | ||||||
| This function must be the first function to call, and it returns a CURL handle |  | ||||||
| that you shall use as input to the other easy-functions. The init calls |  | ||||||
| intializes curl and this call MUST have a corresponding call to |  | ||||||
| .I curl_easy_cleanup |  | ||||||
| when the operation is complete. |  | ||||||
|  |  | ||||||
| On win32 systems, if you want to init the winsock stuff manually, libcurl will |  | ||||||
| not do that for you. WSAStartup() and WSACleanup() should then be called |  | ||||||
| accordingly.  If you want libcurl to handle this, use the CURL_GLOBAL_WIN32 |  | ||||||
| flag in the initial curl_global_init() call. |  | ||||||
|  |  | ||||||
| Using libcurl 7.7 and later, you should perform all your sequential file |  | ||||||
| transfers using the same curl handle. This enables libcurl to use persistant |  | ||||||
| connections where possible. |  | ||||||
| .SH RETURN VALUE |  | ||||||
| If this function returns NULL, something went wrong and you cannot use the |  | ||||||
| other curl functions. |  | ||||||
| .SH "SEE ALSO" |  | ||||||
| .BR curl_easy_cleanup "(3), " curl_global_init "(3) |  | ||||||
| .SH BUGS |  | ||||||
| Surely there are some, you tell me! |  | ||||||
| @@ -7,7 +7,8 @@ AUTOMAKE_OPTIONS = foreign no-dependencies | |||||||
| EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \ | EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \ | ||||||
| 	     win32sockets.c persistant.c ftpget.c Makefile.example \ | 	     win32sockets.c persistant.c ftpget.c Makefile.example \ | ||||||
| 	     multithread.c getinmemory.c ftpupload.c httpput.c \ | 	     multithread.c getinmemory.c ftpupload.c httpput.c \ | ||||||
| 	     simplessl.c ftpgetresp.c http-post.c | 	     simplessl.c ftpgetresp.c http-post.c post-callback.c \ | ||||||
|  | 	     multi-app.c multi-double.c multi-single.c multi-post.c | ||||||
|  |  | ||||||
| all: | all: | ||||||
| 	@echo "done" | 	@echo "done" | ||||||
|   | |||||||
| @@ -26,7 +26,11 @@ size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream) | |||||||
|   return fread(ptr, size, nmemb, stream); |   return fread(ptr, size, nmemb, stream); | ||||||
| } | } | ||||||
|  |  | ||||||
| int my_progress_func(GtkWidget *Bar, int t, int d) | int my_progress_func(GtkWidget *Bar, | ||||||
|  |                      double t, /* dltotal */ | ||||||
|  |                      double d, /* dlnow */ | ||||||
|  |                      double ultotal, | ||||||
|  |                      double ulnow) | ||||||
| { | { | ||||||
| /*  printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/ | /*  printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/ | ||||||
|   gdk_threads_enter(); |   gdk_threads_enter(); | ||||||
| @@ -50,6 +54,7 @@ void *curl_thread(void *ptr) | |||||||
|     curl_easy_setopt(curl, CURLOPT_URL, url); |     curl_easy_setopt(curl, CURLOPT_URL, url); | ||||||
|     curl_easy_setopt(curl, CURLOPT_FILE, outfile); |     curl_easy_setopt(curl, CURLOPT_FILE, outfile); | ||||||
|     curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func); |     curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func); | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); | ||||||
|     curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func); |     curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func); | ||||||
|     curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar); |     curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar); | ||||||
|      |      | ||||||
|   | |||||||
| @@ -1,4 +1,12 @@ | |||||||
| /*
 | /*****************************************************************************
 | ||||||
|  |  *                                  _   _ ____  _      | ||||||
|  |  *  Project                     ___| | | |  _ \| |     | ||||||
|  |  *                             / __| | | | |_) | |     | ||||||
|  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  |  *                             \___|\___/|_| \_\_____| | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  * This is an example application source code using the multi interface. |  * This is an example application source code using the multi interface. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @@ -9,10 +17,8 @@ | |||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
| 
 | /* curl stuff */ | ||||||
| /* To start with, we include the header from the lib directory. This should
 | #include <curl/curl.h> | ||||||
|    later of course be moved to the proper include dir. */ |  | ||||||
| #include "../lib/multi.h" |  | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Download a HTTP file and upload an FTP file simultaneously. |  * Download a HTTP file and upload an FTP file simultaneously. | ||||||
| @@ -1,5 +1,13 @@ | |||||||
| /*
 | /*****************************************************************************
 | ||||||
|  * This is a simple example using the multi interface. |  *                                  _   _ ____  _      | ||||||
|  |  *  Project                     ___| | | |  _ \| |     | ||||||
|  |  *                             / __| | | | |_) | |     | ||||||
|  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  |  *                             \___|\___/|_| \_\_____| | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |  * This is a very simple example using the multi interface. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| @@ -9,9 +17,8 @@ | |||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
| /* To start with, we include the header from the lib directory. This should
 | /* curl stuff */ | ||||||
|    later of course be moved to the proper include dir. */ | #include <curl/curl.h> | ||||||
| #include "../lib/multi.h" |  | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Simply download two HTTP files! |  * Simply download two HTTP files! | ||||||
							
								
								
									
										126
									
								
								docs/examples/multi-post.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								docs/examples/multi-post.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | |||||||
|  | /***************************************************************************** | ||||||
|  |  *                                  _   _ ____  _      | ||||||
|  |  *  Project                     ___| | | |  _ \| |     | ||||||
|  |  *                             / __| | | | |_) | |     | ||||||
|  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  |  *                             \___|\___/|_| \_\_____| | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |  * This is an example application source code using the multi interface | ||||||
|  |  * to do a multipart formpost without "blocking". | ||||||
|  |  */ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <sys/time.h> | ||||||
|  |  | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | int main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |   CURL *curl; | ||||||
|  |   CURLcode res; | ||||||
|  |  | ||||||
|  |   CURLM *multi_handle; | ||||||
|  |   int still_running; | ||||||
|  |  | ||||||
|  |   struct HttpPost *formpost=NULL; | ||||||
|  |   struct HttpPost *lastptr=NULL; | ||||||
|  |   struct curl_slist *headerlist=NULL; | ||||||
|  |   char buf[] = "Expect:"; | ||||||
|  |  | ||||||
|  |   /* Fill in the file upload field */ | ||||||
|  |   curl_formadd(&formpost, | ||||||
|  |                &lastptr, | ||||||
|  |                CURLFORM_COPYNAME, "sendfile", | ||||||
|  |                CURLFORM_FILE, "postit2.c", | ||||||
|  |                CURLFORM_END); | ||||||
|  |  | ||||||
|  |   /* Fill in the filename field */ | ||||||
|  |   curl_formadd(&formpost, | ||||||
|  |                &lastptr, | ||||||
|  |                CURLFORM_COPYNAME, "filename", | ||||||
|  |                CURLFORM_COPYCONTENTS, "postit2.c", | ||||||
|  |                CURLFORM_END); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /* Fill in the submit field too, even if this is rarely needed */ | ||||||
|  |   curl_formadd(&formpost, | ||||||
|  |                &lastptr, | ||||||
|  |                CURLFORM_COPYNAME, "submit", | ||||||
|  |                CURLFORM_COPYCONTENTS, "send", | ||||||
|  |                CURLFORM_END); | ||||||
|  |  | ||||||
|  |   curl = curl_easy_init(); | ||||||
|  |   multi_handle = curl_multi_init(); | ||||||
|  |  | ||||||
|  |   /* initalize custom header list (stating that Expect: 100-continue is not | ||||||
|  |      wanted */ | ||||||
|  |   headerlist = curl_slist_append(headerlist, buf); | ||||||
|  |   if(curl && multi_handle) { | ||||||
|  |     int perform=0; | ||||||
|  |  | ||||||
|  |     /* what URL that receives this POST */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_URL, | ||||||
|  |                      "http://www.fillinyoururl.com/upload.cgi"); | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | ||||||
|  |  | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); | ||||||
|  |  | ||||||
|  |     curl_multi_add_handle(multi_handle, curl); | ||||||
|  |  | ||||||
|  |     while(CURLM_CALL_MULTI_PERFORM == | ||||||
|  |           curl_multi_perform(multi_handle, &still_running)); | ||||||
|  |  | ||||||
|  |     while(still_running) { | ||||||
|  |       struct timeval timeout; | ||||||
|  |       int rc; /* select() return code */ | ||||||
|  |  | ||||||
|  |       fd_set fdread; | ||||||
|  |       fd_set fdwrite; | ||||||
|  |       fd_set fdexcep; | ||||||
|  |       int maxfd; | ||||||
|  |  | ||||||
|  |       FD_ZERO(&fdread); | ||||||
|  |       FD_ZERO(&fdwrite); | ||||||
|  |       FD_ZERO(&fdexcep); | ||||||
|  |  | ||||||
|  |       /* set a suitable timeout to play around with */ | ||||||
|  |       timeout.tv_sec = 1; | ||||||
|  |       timeout.tv_usec = 0; | ||||||
|  |  | ||||||
|  |       /* get file descriptors from the transfers */ | ||||||
|  |       curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||||
|  |  | ||||||
|  |       rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||||
|  |  | ||||||
|  |       switch(rc) { | ||||||
|  |       case -1: | ||||||
|  |         /* select error */ | ||||||
|  |         break; | ||||||
|  |       case 0: | ||||||
|  |         printf("timeout!\n"); | ||||||
|  |       default: | ||||||
|  |         /* timeout or readable/writable sockets */ | ||||||
|  |         printf("perform!\n"); | ||||||
|  |         while(CURLM_CALL_MULTI_PERFORM == | ||||||
|  |               curl_multi_perform(multi_handle, &still_running)); | ||||||
|  |         printf("running: %d!\n", still_running); | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     curl_multi_cleanup(multi_handle); | ||||||
|  |  | ||||||
|  |     /* always cleanup */ | ||||||
|  |     curl_easy_cleanup(curl); | ||||||
|  |  | ||||||
|  |     /* then cleanup the formpost chain */ | ||||||
|  |     curl_formfree(formpost); | ||||||
|  |  | ||||||
|  |     /* free slist */ | ||||||
|  |     curl_slist_free_all (headerlist); | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
| @@ -1,4 +1,12 @@ | |||||||
| /*
 | /*****************************************************************************
 | ||||||
|  |  *                                  _   _ ____  _      | ||||||
|  |  *  Project                     ___| | | |  _ \| |     | ||||||
|  |  *                             / __| | | | |_) | |     | ||||||
|  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  |  *                             \___|\___/|_| \_\_____| | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  * This is a very simple example using the multi interface. |  * This is a very simple example using the multi interface. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @@ -9,9 +17,8 @@ | |||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
| /* To start with, we include the header from the lib directory. This should
 | /* curl stuff */ | ||||||
|    later of course be moved to the proper include dir. */ | #include <curl/curl.h> | ||||||
| #include "../lib/multi.h" |  | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Simply download a HTTP file. |  * Simply download a HTTP file. | ||||||
							
								
								
									
										89
									
								
								docs/examples/post-callback.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								docs/examples/post-callback.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | /***************************************************************************** | ||||||
|  |  *                                  _   _ ____  _      | ||||||
|  |  *  Project                     ___| | | |  _ \| |     | ||||||
|  |  *                             / __| | | | |_) | |     | ||||||
|  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  |  *                             \___|\___/|_| \_\_____| | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |  * An example source code that issues a HTTP POST and we provide the actual | ||||||
|  |  * data through a read callback. | ||||||
|  |  * | ||||||
|  |  * Please be aware of the fact that the size of the posted data MUST be | ||||||
|  |  * specified before the transfer is being made (with CURLOPT_POSTFIELDSIZE). | ||||||
|  |  * This requirement will change when libcurl starts supporting chunked-encoded | ||||||
|  |  * sends. | ||||||
|  |  * | ||||||
|  |  * This example requires libcurl 7.9.6 or later. | ||||||
|  |  */ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | #if LIBCURL_VERSION_NUM < 0x070906 | ||||||
|  | #error this example source requires libcurl 7.9.6 or newer | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | char data[]="this is what we post to the silly web server"; | ||||||
|  |  | ||||||
|  | struct WriteThis { | ||||||
|  |   char *readptr; | ||||||
|  |   int sizeleft; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) | ||||||
|  | { | ||||||
|  |   struct WriteThis *pooh = (struct WriteThis *)userp; | ||||||
|  |  | ||||||
|  |   if(size*nmemb < 1) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  |   if(pooh->sizeleft) { | ||||||
|  |     *(char *)ptr = pooh->readptr[0]; /* copy one single byte */ | ||||||
|  |     pooh->readptr++;                 /* advance pointer */ | ||||||
|  |     pooh->sizeleft--;                /* less data left */ | ||||||
|  |     return 1;                        /* we return 1 byte at a time! */ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return -1;                         /* no more data left to deliver */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(void) | ||||||
|  | { | ||||||
|  |   CURL *curl; | ||||||
|  |   CURLcode res; | ||||||
|  |  | ||||||
|  |   struct WriteThis pooh; | ||||||
|  |  | ||||||
|  |   pooh.readptr = data; | ||||||
|  |   pooh.sizeleft = strlen(data); | ||||||
|  |  | ||||||
|  |   curl = curl_easy_init(); | ||||||
|  |   if(curl) { | ||||||
|  |     /* First set the URL that is about to receive our POST. */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_URL, | ||||||
|  |                      "http://receivingsite.com.pooh/index.cgi"); | ||||||
|  |     /* Now specify we want to POST data */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_POST, TRUE); | ||||||
|  |  | ||||||
|  |     /* Set the expected POST size */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pooh.sizeleft); | ||||||
|  |  | ||||||
|  |     /* we want to use our own read function */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); | ||||||
|  |  | ||||||
|  |     /* pointer to pass to our read function */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_INFILE, &pooh); | ||||||
|  |  | ||||||
|  |     /* get verbose debug output please */ | ||||||
|  |     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | ||||||
|  |  | ||||||
|  |     /* Perform the request, res will get the return code */ | ||||||
|  |     res = curl_easy_perform(curl); | ||||||
|  |  | ||||||
|  |     /* always cleanup */ | ||||||
|  |     curl_easy_cleanup(curl); | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
| @@ -9,7 +9,7 @@ PROGRAMMING WITH LIBCURL | |||||||
|  |  | ||||||
| About this Document | About this Document | ||||||
|  |  | ||||||
|  This document will attempt to describe the general principle and some basic |  This document attempts to describe the general principles and some basic | ||||||
|  approaches to consider when programming with libcurl. The text will focus |  approaches to consider when programming with libcurl. The text will focus | ||||||
|  mainly on the C interface but might apply fairly well on other interfaces as |  mainly on the C interface but might apply fairly well on other interfaces as | ||||||
|  well as they usually follow the C one pretty closely. |  well as they usually follow the C one pretty closely. | ||||||
| @@ -114,7 +114,7 @@ Global Preparation | |||||||
|  call initialized. |  call initialized. | ||||||
|  |  | ||||||
|  Repeated calls to curl_global_init() and curl_global_cleanup() should be |  Repeated calls to curl_global_init() and curl_global_cleanup() should be | ||||||
|  avoided. They should be called once each. |  avoided. They should only be called once each. | ||||||
|  |  | ||||||
| Handle the Easy libcurl | Handle the Easy libcurl | ||||||
|  |  | ||||||
| @@ -413,8 +413,8 @@ HTTP POSTing | |||||||
|  The following example sets two simple text parts with plain textual contents, |  The following example sets two simple text parts with plain textual contents, | ||||||
|  and then a file with binary contents and upload the whole thing. |  and then a file with binary contents and upload the whole thing. | ||||||
|  |  | ||||||
|     struct HttpPost *post=NULL; |     struct curl_httppost *post=NULL; | ||||||
|     struct HttpPost *last=NULL; |     struct curl_httppost *last=NULL; | ||||||
|     curl_formadd(&post, &last, |     curl_formadd(&post, &last, | ||||||
|                  CURLFORM_COPYNAME, "name", |                  CURLFORM_COPYNAME, "name", | ||||||
|                  CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); |                  CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); | ||||||
| @@ -470,7 +470,30 @@ HTTP POSTing | |||||||
|  |  | ||||||
| Showing Progress | Showing Progress | ||||||
|  |  | ||||||
|  [ built-in progress meter, progress callback ] |  For historical and traditional reasons, libcurl has a built-in progress meter | ||||||
|  |  that can be switched on and then makes it presents a progress meter in your | ||||||
|  |  terminal. | ||||||
|  |  | ||||||
|  |  Switch on the progress meter by, oddly enough, set CURLOPT_NOPROGRESS to | ||||||
|  |  FALSE. This option is set to TRUE by default. | ||||||
|  |  | ||||||
|  |  For most applications however, the built-in progress meter is useless and | ||||||
|  |  what instead is interesting is the ability to specify a progress | ||||||
|  |  callback. The function pointer you pass to libcurl will then be called on | ||||||
|  |  irregular intervals with information about the current transfer. | ||||||
|  |  | ||||||
|  |  Set the progress callback by using CURLOPT_PROGRESSFUNCTION. And pass a | ||||||
|  |  pointer to a function that matches this prototype: | ||||||
|  |  | ||||||
|  |         int progress_callback(void *clientp, | ||||||
|  |                               double dltotal, | ||||||
|  |                               double dlnow, | ||||||
|  |                               double ultotal, | ||||||
|  |                               double ulnow); | ||||||
|  |  | ||||||
|  |  If any of the input arguments is unknown, a 0 will be passed. The first | ||||||
|  |  argument, the 'clientp' is the pointer you pass to libcurl with | ||||||
|  |  CURLOPT_PROGRESSDATA. libcurl won't touch it. | ||||||
|  |  | ||||||
|  |  | ||||||
| libcurl with C++ | libcurl with C++ | ||||||
| @@ -741,6 +764,15 @@ Customizing Operations | |||||||
|  consideration and you should be aware that you may violate the HTTP protocol |  consideration and you should be aware that you may violate the HTTP protocol | ||||||
|  when doing so. |  when doing so. | ||||||
|  |  | ||||||
|  |  There's only one aspect left in the HTTP requests that we haven't yet | ||||||
|  |  mentioned how to modify: the version field. All HTTP requests includes the | ||||||
|  |  version number to tell the server which version we support. libcurl speak | ||||||
|  |  HTTP 1.1 by default. Some very old servers don't like getting 1.1-requests | ||||||
|  |  and when dealing with stubborn old things like that, you can tell libcurl to | ||||||
|  |  use 1.0 instead by doing something like this: | ||||||
|  |  | ||||||
|  |     curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURLHTTP_VERSION_1_0); | ||||||
|  |  | ||||||
|  Not all protocols are HTTP-like, and thus the above may not help you when you |  Not all protocols are HTTP-like, and thus the above may not help you when you | ||||||
|  want to make for example your FTP transfers to behave differently. |  want to make for example your FTP transfers to behave differently. | ||||||
|  |  | ||||||
| @@ -770,21 +802,123 @@ Customizing Operations | |||||||
|  instead be called CURLOPT_POSTQUOTE and used the exact same way. |  instead be called CURLOPT_POSTQUOTE and used the exact same way. | ||||||
|  |  | ||||||
|  The custom FTP command will be issued to the server in the same order they |  The custom FTP command will be issued to the server in the same order they | ||||||
|  are built in the list, and if a command gets an error code returned back from |  are added to the list, and if a command gets an error code returned back from | ||||||
|  the server no more commands will be issued and libcurl will bail out with an |  the server, no more commands will be issued and libcurl will bail out with an | ||||||
|  error code. Note that if you use CURLOPT_QUOTE to send commands before a |  error code (CURLE_FTP_QUOTE_ERROR). Note that if you use CURLOPT_QUOTE to | ||||||
|  transfer, no transfer will actually take place then. |  send commands before a transfer, no transfer will actually take place when a | ||||||
|  |  quote command has failed. | ||||||
|  |  | ||||||
|  |  If you set the CURLOPT_HEADER to true, you will tell libcurl to get | ||||||
|  |  information about the target file and output "headers" about it. The headers | ||||||
|  |  will be in "HTTP-style", looking like they do in HTTP. | ||||||
|  |  | ||||||
|  |  The option to enable headers or to run custom FTP commands may be useful to | ||||||
|  |  combine with CURLOPT_NOBODY. If this option is set, no actual file content | ||||||
|  |  transfer will be performed. | ||||||
|  |  | ||||||
|  [ custom FTP commands without transfer, FTP "header-only", HTTP 1.0 ] |  | ||||||
|  |  | ||||||
| Cookies Without Chocolate Chips | Cookies Without Chocolate Chips | ||||||
|  |  | ||||||
|  [ set cookies, read cookies from file, cookie-jar ] |  In the HTTP sense, a cookie is a name with an associated value. A server | ||||||
|  |  sends the name and value to the client, and expects it to get sent back on | ||||||
|  |  every subsequent request to the server that matches the particular conditions | ||||||
|  |  set. The conditions include that the domain name and path match and that the | ||||||
|  |  cookie hasn't become too old. | ||||||
|  |  | ||||||
|  |  In real-world cases, servers send new cookies to replace existing one to | ||||||
|  |  update them. Server use cookies to "track" users and to keep "sessions". | ||||||
|  |  | ||||||
|  |  Cookies are sent from server to clients with the header Set-Cookie: and | ||||||
|  |  they're sent from clients to servers with the Cookie: header. | ||||||
|  |  | ||||||
|  |  To just send whatever cookie you want to a server, you can use CURLOPT_COOKIE | ||||||
|  |  to set a cookie string like this: | ||||||
|  |  | ||||||
|  |     curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;"); | ||||||
|  |  | ||||||
|  |  In many cases, that is not enough. You might want to dynamicly save whatever | ||||||
|  |  cookies the remote server passes to you, and make sure those cookies are then | ||||||
|  |  use accordingly on later requests. | ||||||
|  |  | ||||||
|  |  One way to do this, is to save all headers you receive in a plain file and | ||||||
|  |  when you make a request, you tell libcurl to read the previous headers to | ||||||
|  |  figure out which cookies to use. Set header file to read cookies from with | ||||||
|  |  CURLOPT_COOKIEFILE. | ||||||
|  |  | ||||||
|  |  The CURLOPT_COOKIEFILE option also automaticly enables the cookie parser in | ||||||
|  |  libcurl. Until the cookie parser is enabled, libcurl will not parse or | ||||||
|  |  understand incoming cookies and they will just be ignored. However, when the | ||||||
|  |  parser is enabled the cookies will be understood and the cookies will be kept | ||||||
|  |  in memory and used properly in subsequent requests when the same handle is | ||||||
|  |  used. Many times this is enough, and you may not have to save the cookies to | ||||||
|  |  disk at all. Note that the file you specify to CURLOPT_COOKIEFILE doesn't | ||||||
|  |  have to exist to enable the parser, so a common way to just enable the parser | ||||||
|  |  and not read able might be to use a file name you know doesn't exist. | ||||||
|  |  | ||||||
|  |  If you rather use existing cookies that you've previously received with your | ||||||
|  |  Netscape or Mozilla browsers, you can make libcurl use that cookie file as | ||||||
|  |  input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will | ||||||
|  |  automaticly find out what kind of file it is and act accordingly. | ||||||
|  |  | ||||||
|  |  The perhaps most advanced cookie operation libcurl offers, is saving the | ||||||
|  |  entire internal cookie state back into a Netscape/Mozilla formatted cookie | ||||||
|  |  file. We call that the cookie-jar. When you set a file name with | ||||||
|  |  CURLOPT_COOKIEJAR, that file name will be created and all received cookies | ||||||
|  |  will be stored in it when curl_easy_cleanup() is called. This enabled cookies | ||||||
|  |  to get passed on properly between multiple handles without any information | ||||||
|  |  getting lost. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | FTP Peculiarities We Need | ||||||
|  |  | ||||||
|  |  FTP transfers use a second TCP/IP connection for the data transfer. This is | ||||||
|  |  usually a fact you can forget and ignore but at times this fact will come | ||||||
|  |  back to haunt you. libcurl offers several different ways to custom how the | ||||||
|  |  second connection is being made. | ||||||
|  |  | ||||||
|  |  libcurl can either connect to the server a second time or tell the server to | ||||||
|  |  connect back to it. The first option is the default and it is also what works | ||||||
|  |  best for all the people behind firewalls, NATs or IP-masquarading setups. | ||||||
|  |  libcurl then tells the server to open up a new port and wait for a second | ||||||
|  |  connection. This is by default attempted with EPSV first, and if that doesn't | ||||||
|  |  work it tries PASV instead. (EPSV is an extension to the original FTP spec | ||||||
|  |  and does not exist nor work on all FTP servers.) | ||||||
|  |  | ||||||
|  |  You can prevent libcurl from first trying the EPSV command by setting | ||||||
|  |  CURLOPT_FTP_USE_EPSV to FALSE. | ||||||
|  |  | ||||||
|  |  In some cases, you will prefer to have the server connect back to you for the | ||||||
|  |  second connection. This might be when the server is perhaps behind a firewall | ||||||
|  |  or something and only allows connections on a single port. libcurl then | ||||||
|  |  informs the remote server which IP address and port number to connect to. | ||||||
|  |  This is made with the CURLOPT_FTPPORT option. If you set it to "-", libcurl | ||||||
|  |  will use your system's "default IP address". If you want to use a particular | ||||||
|  |  IP, you can set the full IP address, a host name to resolve to an IP address | ||||||
|  |  or even a local network interface name that libcurl will get the IP address | ||||||
|  |  from. | ||||||
|  |  | ||||||
|  |  | ||||||
| Headers Equal Fun | Headers Equal Fun | ||||||
|  |  | ||||||
|  [ use the header callback for HTTP, FTP etc ] |  Some protocols provide "headers", meta-data separated from the normal | ||||||
|  |  data. These headers are by default not included in the normal data stream, | ||||||
|  |  but you can make them appear in the data stream by setting CURLOPT_HEADER to | ||||||
|  |  TRUE. | ||||||
|  |  | ||||||
|  |  What might be even more useful, is libcurl's ability to separate the headers | ||||||
|  |  from the data and thus make the callbacks differ. You can for example set a | ||||||
|  |  different pointer to pass to the ordinary write callback by setting | ||||||
|  |  CURLOPT_WRITEHEADER. | ||||||
|  |  | ||||||
|  |  Or, you can set an entirely separate function to receive the headers, by | ||||||
|  |  using CURLOPT_HEADERFUNCTION. | ||||||
|  |  | ||||||
|  |  The headers are passed to the callback function one by one, and you can | ||||||
|  |  depend on that fact. It makes it easier for you to add custom header parsers | ||||||
|  |  etc. | ||||||
|  |  | ||||||
|  |  "Headers" for FTP transfers equal all the FTP server responses. They aren't | ||||||
|  |  actually true headers, but in this case we pretend they are! ;-) | ||||||
|  |  | ||||||
|  |  | ||||||
| Post Transfer Information | Post Transfer Information | ||||||
| @@ -794,7 +928,61 @@ Post Transfer Information | |||||||
|  |  | ||||||
| Security Considerations | Security Considerations | ||||||
|  |  | ||||||
|  [ ps output, netrc plain text, plain text protocols / base64 ] |  libcurl is in itself not insecure. If used the right way, you can use libcurl | ||||||
|  |  to transfer data pretty safely. | ||||||
|  |  | ||||||
|  |  There are of course many things to consider that may loosen up this | ||||||
|  |  situation: | ||||||
|  |  | ||||||
|  |   Command Lines | ||||||
|  |  | ||||||
|  |     If you use a command line tool (such as curl) that uses libcurl, and you | ||||||
|  |     give option to the tool on the command line those options can very likely | ||||||
|  |     get read by other users of your system when they use 'ps' or other tools | ||||||
|  |     to list currently running processes. | ||||||
|  |  | ||||||
|  |     To avoid this problem, never feed sensitive things to programs using | ||||||
|  |     command line options. | ||||||
|  |  | ||||||
|  |   .netrc | ||||||
|  |  | ||||||
|  |     .netrc is a pretty handy file/feature that allows you to login quickly and | ||||||
|  |     automaticly to frequently visited sites. The file contains passwords in | ||||||
|  |     clear text and is a real security risk. In some cases, your .netrc is also | ||||||
|  |     stored in a home directory that is NFS mounted or used on another network | ||||||
|  |     based file system, so the clear text password will fly through your | ||||||
|  |     network every time anyone reads that file! | ||||||
|  |  | ||||||
|  |     To avoid this problem, don't use .netrc files and never store passwords in | ||||||
|  |     plain text anywhere. | ||||||
|  |  | ||||||
|  |   Clear Text Passwords | ||||||
|  |  | ||||||
|  |     Many of the protocols libcurl supports send name and password unencrypted | ||||||
|  |     as clear text (HTTP Basic authentication, FTP, TELNET etc). It is very | ||||||
|  |     easy for anyone on your network or a network nearby yours, to just fire up | ||||||
|  |     a network analyzer tool and evesdrop on your passwords. Don't let the fact | ||||||
|  |     that HTTP uses base64 encoded passwords fool you. They may not look | ||||||
|  |     readable at a first glance, but they very easily "deciphered" by anyone | ||||||
|  |     within seconds. | ||||||
|  |  | ||||||
|  |     To avoid this problem, use protocols that don't let snoopers see your | ||||||
|  |     password: HTTPS, FTPS and FTP-kerberos are a few examples. HTTP Digest | ||||||
|  |     authentication allows this too, but isn't supported by libcurl as of this | ||||||
|  |     writing. | ||||||
|  |  | ||||||
|  |   Showing What You Do | ||||||
|  |  | ||||||
|  |     On a related issue, be aware that even in situations like when you have | ||||||
|  |     problems with libcurl and ask somone for help, everything you reveal in | ||||||
|  |     order to get best possible help might also impose certain security related | ||||||
|  |     risks. Host names, user names, paths, operating system specifics etc (not | ||||||
|  |     to mention passwords of course) may in fact be used by intruders to gain | ||||||
|  |     additional information of a potential target. | ||||||
|  |  | ||||||
|  |     To avoid this problem, you must of course use your common sense. Often, | ||||||
|  |     you can just edit out the senstive data or just rearch/replace your true | ||||||
|  |     information with faked data. | ||||||
|  |  | ||||||
|  |  | ||||||
| SSL, Certificates and Other Tricks | SSL, Certificates and Other Tricks | ||||||
|   | |||||||
							
								
								
									
										86
									
								
								docs/libcurl/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								docs/libcurl/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | # | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  |  | ||||||
|  | AUTOMAKE_OPTIONS = foreign no-dependencies | ||||||
|  |  | ||||||
|  | man_MANS = \ | ||||||
|  | 	curl_easy_cleanup.3 \ | ||||||
|  | 	curl_easy_getinfo.3 \ | ||||||
|  | 	curl_easy_init.3 \ | ||||||
|  | 	curl_easy_perform.3 \ | ||||||
|  | 	curl_easy_setopt.3 \ | ||||||
|  | 	curl_easy_duphandle.3 \ | ||||||
|  | 	curl_formparse.3 \ | ||||||
|  | 	curl_formadd.3 \ | ||||||
|  | 	curl_formfree.3 \ | ||||||
|  | 	curl_getdate.3 \ | ||||||
|  | 	curl_getenv.3 \ | ||||||
|  | 	curl_slist_append.3 \ | ||||||
|  | 	curl_slist_free_all.3 \ | ||||||
|  | 	curl_version.3 \ | ||||||
|  | 	curl_escape.3 \ | ||||||
|  | 	curl_unescape.3 \ | ||||||
|  | 	curl_strequal.3 \ | ||||||
|  | 	curl_strnequal.3 \ | ||||||
|  | 	curl_mprintf.3 \ | ||||||
|  | 	curl_global_init.3 \ | ||||||
|  | 	curl_global_cleanup.3 \ | ||||||
|  | 	libcurl.3 \ | ||||||
|  | 	curl_multi_add_handle.3 \ | ||||||
|  | 	curl_multi_cleanup.3 \ | ||||||
|  | 	curl_multi_fdset.3 \ | ||||||
|  | 	curl_multi_info_read.3 \ | ||||||
|  | 	curl_multi_init.3 \ | ||||||
|  | 	curl_multi_perform.3 \ | ||||||
|  | 	curl_multi_remove_handle.3 \ | ||||||
|  | 	libcurl-multi.3 \ | ||||||
|  | 	libcurl-errors.3 | ||||||
|  |  | ||||||
|  | HTMLPAGES = \ | ||||||
|  | 	curl_easy_cleanup.html \ | ||||||
|  | 	curl_easy_getinfo.html \ | ||||||
|  | 	curl_easy_init.html \ | ||||||
|  | 	curl_easy_perform.html \ | ||||||
|  | 	curl_easy_setopt.html \ | ||||||
|  | 	curl_easy_duphandle.html \ | ||||||
|  | 	curl_formadd.html \ | ||||||
|  | 	curl_formparse.html \ | ||||||
|  | 	curl_formfree.html \ | ||||||
|  | 	curl_getdate.html \ | ||||||
|  | 	curl_getenv.html \ | ||||||
|  | 	curl_slist_append.html \ | ||||||
|  | 	curl_slist_free_all.html \ | ||||||
|  | 	curl_version.html \ | ||||||
|  | 	curl_escape.html \ | ||||||
|  | 	curl_unescape.html \ | ||||||
|  | 	curl_strequal.html \ | ||||||
|  | 	curl_strnequal.html \ | ||||||
|  | 	curl_mprintf.html \ | ||||||
|  | 	curl_global_init.html \ | ||||||
|  | 	curl_global_cleanup.html \ | ||||||
|  | 	libcurl.html \ | ||||||
|  | 	curl_multi_add_handle.html \ | ||||||
|  | 	curl_multi_cleanup.html \ | ||||||
|  | 	curl_multi_fdset.html \ | ||||||
|  | 	curl_multi_info_read.html \ | ||||||
|  | 	curl_multi_init.html \ | ||||||
|  | 	curl_multi_perform.html \ | ||||||
|  | 	curl_multi_remove_handle.html \ | ||||||
|  | 	libcurl-multi.html \ | ||||||
|  | 	libcurl-errors.html \ | ||||||
|  | 	index.html | ||||||
|  |  | ||||||
|  | EXTRA_DIST = $(man_MANS) $(HTMLPAGES) | ||||||
|  |  | ||||||
|  | MAN2HTML= gnroff -man $< | man2html >$@ | ||||||
|  |  | ||||||
|  | SUFFIXES = .1 .3 .html | ||||||
|  |  | ||||||
|  | html: $(HTMLPAGES) | ||||||
|  |  | ||||||
|  | .3.html: | ||||||
|  | 	$(MAN2HTML) | ||||||
|  |  | ||||||
|  | .1.html: | ||||||
|  | 	$(MAN2HTML) | ||||||
							
								
								
									
										25
									
								
								docs/libcurl/curl_easy_cleanup.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								docs/libcurl/curl_easy_cleanup.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | .\" You can view this file with: | ||||||
|  | .\" nroff -man [file] | ||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_easy_cleanup 3 "4 March 2002" "libcurl 7.7" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_easy_cleanup - End a libcurl easy session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | .B #include <curl/curl.h> | ||||||
|  | .sp | ||||||
|  | .BI "void curl_easy_cleanup(CURL *" handle ");" | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | This function must be the last function to call for an easy session. It is the | ||||||
|  | opposite of the \fIcurl_easy_init\fP function and must be called with the same | ||||||
|  | \fIhandle\fP as input that the curl_easy_init call returned. | ||||||
|  |  | ||||||
|  | This will effectively close all connections this handle has used and possibly | ||||||
|  | has kept open until now. Don't call this function if you intend to transfer | ||||||
|  | more files. | ||||||
|  | .SH RETURN VALUE | ||||||
|  | None | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_easy_init "(3), " | ||||||
|  |  | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| .\" nroff -man [file] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $Id$ | ||||||
| .\" | .\" | ||||||
| .TH curl_easy_init 3 "31 Jan 2001" "libcurl 7.9.4" "libcurl Manual" | .TH curl_easy_init 3 "25 Apr 2002" "libcurl 7.9.7" "libcurl Manual" | ||||||
| .SH NAME | .SH NAME | ||||||
| curl_easy_getinfo - Extract information from a curl session (added in 7.4) | curl_easy_getinfo - Extract information from a curl session (added in 7.4) | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| @@ -38,7 +38,9 @@ CURLOPT_FILETIME option to \fIcurl_easy_setopt(3)\fP. (Added in 7.5) | |||||||
| .TP | .TP | ||||||
| .B CURLINFO_TOTAL_TIME | .B CURLINFO_TOTAL_TIME | ||||||
| Pass a pointer to a double to receive the total transaction time in seconds | Pass a pointer to a double to receive the total transaction time in seconds | ||||||
| for the previous transfer. | for the previous transfer. This time does not include the connect time, so if | ||||||
|  | you want the complete operation time, you should add the | ||||||
|  | CURLINFO_CONNECT_TIME. | ||||||
| .TP | .TP | ||||||
| .B CURLINFO_NAMELOOKUP_TIME | .B CURLINFO_NAMELOOKUP_TIME | ||||||
| Pass a pointer to a double to receive the time, in seconds, it took from the | Pass a pointer to a double to receive the time, in seconds, it took from the | ||||||
| @@ -60,6 +62,16 @@ start until the first byte is just about to be transfered. This includes | |||||||
| CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate | CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate | ||||||
| the result. | the result. | ||||||
| .TP | .TP | ||||||
|  | .B CURLINFO_REDIRECT_TIME | ||||||
|  | Pass a pointer to a double to receive the total time, in seconds, it took for | ||||||
|  | all redirection steps include name lookup, connect, pretransfer and transfer | ||||||
|  | before final transaction was started. CURLINFO_REDIRECT_TIME contains the | ||||||
|  | complete execution time for multiple redirections.  (Added in 7.9.7) | ||||||
|  | .TP | ||||||
|  | .B CURLINFO_REDIRECT_COUNT | ||||||
|  | Pass a pointer to a long to receive the total number of redirections that were | ||||||
|  | actually followed.  (Added in 7.9.7) | ||||||
|  | .TP | ||||||
| .B CURLINFO_SIZE_UPLOAD | .B CURLINFO_SIZE_UPLOAD | ||||||
| Pass a pointer to a double to receive the total amount of bytes that were | Pass a pointer to a double to receive the total amount of bytes that were | ||||||
| uploaded. | uploaded. | ||||||
							
								
								
									
										25
									
								
								docs/libcurl/curl_easy_init.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								docs/libcurl/curl_easy_init.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | .\" You can view this file with: | ||||||
|  | .\" nroff -man [file] | ||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_easy_init 3 "4 March 2002" "libcurl 7.8.1" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_easy_init - Start a libcurl easy session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | .B #include <curl/curl.h> | ||||||
|  | .sp | ||||||
|  | .BI "CURL *curl_easy_init( );" | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | This function must be the first function to call, and it returns a CURL easy | ||||||
|  | handle that you must use as input to other easy-functions. curl_easy_init | ||||||
|  | intializes curl and this call MUST have a corresponding call to | ||||||
|  | \fIcurl_easy_cleanup\fP when the operation is complete. | ||||||
|  |  | ||||||
|  | .SH RETURN VALUE | ||||||
|  | If this function returns NULL, something went wrong and you cannot use the | ||||||
|  | other curl functions. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_easy_cleanup "(3), " curl_global_init "(3) | ||||||
|  | .SH BUGS | ||||||
|  | Surely there are some, you tell me! | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| .\" nroff -man [file] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $Id$ | ||||||
| .\" | .\" | ||||||
| .TH curl_easy_setopt 3 "10 Dec 2001" "libcurl 7.9.2" "libcurl Manual" | .TH curl_easy_setopt 3 "3 May 2002" "libcurl 7.9.6" "libcurl Manual" | ||||||
| .SH NAME | .SH NAME | ||||||
| curl_easy_setopt - Set curl easy-session options | curl_easy_setopt - Set curl easy-session options | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| @@ -35,8 +35,8 @@ The \fIhandle\fP is the return code from a \fIcurl_easy_init(3)\fP or | |||||||
| \fIcurl_easy_duphandle(3)\fP call. | \fIcurl_easy_duphandle(3)\fP call. | ||||||
| .SH OPTIONS | .SH OPTIONS | ||||||
| The options are listed in a sort of random order, but you'll figure it out! | The options are listed in a sort of random order, but you'll figure it out! | ||||||
| .TP 0.8i | .TP 0.4i | ||||||
| .B CURLOPT_FILE | .B CURLOPT_WRITEDATA | ||||||
| Data pointer to pass to the file write function. Note that if you specify the | Data pointer to pass to the file write function. Note that if you specify the | ||||||
| \fICURLOPT_WRITEFUNCTION\fP, this is the pointer you'll get as input. If you | \fICURLOPT_WRITEFUNCTION\fP, this is the pointer you'll get as input. If you | ||||||
| don't use a callback, you must pass a 'FILE *' as libcurl will pass this to | don't use a callback, you must pass a 'FILE *' as libcurl will pass this to | ||||||
| @@ -45,30 +45,35 @@ fwrite() when writing data. | |||||||
| \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use the | \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use the | ||||||
| \fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience | \fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience | ||||||
| crashes. | crashes. | ||||||
|  | 
 | ||||||
|  | This option is also known with the older name \fBCURLOPT_FILE\fP. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_WRITEFUNCTION | .B CURLOPT_WRITEFUNCTION | ||||||
| Function pointer that should match the following prototype: \fBsize_t | Function pointer that should match the following prototype: \fBsize_t | ||||||
| function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This | function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This | ||||||
| function gets called by libcurl as soon as there is data available to pass | function gets called by libcurl as soon as there is data available that needs | ||||||
| available that needs to be saved. The size of the data pointed to by \fIptr\fP | to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP | ||||||
| is \fIsize\fP multiplied with \fInmemb\fP.  Return the number of bytes | multiplied with \fInmemb\fP.  Return the number of bytes actually taken care | ||||||
| actually taken care of. If that amount differs from the amount passed to your | of. If that amount differs from the amount passed to your function, it'll | ||||||
| function, it'll signal an error to the library and it will abort the transfer | signal an error to the library and it will abort the transfer and return | ||||||
| and return \fICURLE_WRITE_ERROR\fP. | \fICURLE_WRITE_ERROR\fP. | ||||||
| 
 | 
 | ||||||
| Set the \fIstream\fP argument with the \fBCURLOPT_FILE\fP option. | Set the \fIstream\fP argument with the \fBCURLOPT_FILE\fP option. | ||||||
| 
 | 
 | ||||||
| \fBNOTE:\fP you will be passed as much data as possible in all invokes, but | \fBNOTE:\fP you will be passed as much data as possible in all invokes, but | ||||||
| you cannot possibly make any assumptions. It may be one byte, it may be | you cannot possibly make any assumptions. It may be one byte, it may be | ||||||
| thousands. | thousands. The maximum amount of data that can be passed to the write callback | ||||||
|  | is defined in the curl.h header file: CURL_MAX_WRITE_SIZE. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_INFILE | .B CURLOPT_READDATA | ||||||
| Data pointer to pass to the file read function. Note that if you specify the | Data pointer to pass to the file read function. Note that if you specify the | ||||||
| \fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you | \fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you | ||||||
| don't specify a read callback, this must be a valid FILE *. | don't specify a read callback, this must be a valid FILE *. | ||||||
| 
 | 
 | ||||||
| \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use a | \fBNOTE:\fP If you're using libcurl as a win32 DLL, you MUST use a | ||||||
| \fICURLOPT_READFUNCTION\fP if you set this option. | \fICURLOPT_READFUNCTION\fP if you set this option. | ||||||
|  | 
 | ||||||
|  | This option is also known with the older name \fBCURLOPT_INFILE\fP. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_READFUNCTION | .B CURLOPT_READFUNCTION | ||||||
| Function pointer that should match the following prototype: \fBsize_t | Function pointer that should match the following prototype: \fBsize_t | ||||||
| @@ -293,6 +298,13 @@ want the transfer to start from. | |||||||
| Pass a pointer to a zero terminated string as parameter. It will be used to | Pass a pointer to a zero terminated string as parameter. It will be used to | ||||||
| set a cookie in the http request. The format of the string should be | set a cookie in the http request. The format of the string should be | ||||||
| [NAME]=[CONTENTS]; Where NAME is the cookie name. | [NAME]=[CONTENTS]; Where NAME is the cookie name. | ||||||
|  | 
 | ||||||
|  | If you need to set mulitple cookies, you need to set them all using a single | ||||||
|  | option and thus you need to concat them all in one single string. Set multiple | ||||||
|  | cookies in one string like this: "name1=content1; name2=content2;" etc. | ||||||
|  | 
 | ||||||
|  | Using this option multiple times will only make the latest string override the | ||||||
|  | previously ones. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_HTTPHEADER | .B CURLOPT_HTTPHEADER | ||||||
| Pass a pointer to a linked list of HTTP headers to pass to the server in your | Pass a pointer to a linked list of HTTP headers to pass to the server in your | ||||||
| @@ -428,8 +440,8 @@ TIMECOND_IFUNMODSINCE. This is a HTTP-only feature. (TBD) | |||||||
| .TP | .TP | ||||||
| .B CURLOPT_TIMEVALUE | .B CURLOPT_TIMEVALUE | ||||||
| Pass a long as parameter. This should be the time in seconds since 1 jan 1970, | Pass a long as parameter. This should be the time in seconds since 1 jan 1970, | ||||||
| and the time will be used as specified in CURLOPT_TIMECONDITION or if that | and the time will be used in a condition as specified with | ||||||
| isn't used, it will be TIMECOND_IFMODSINCE by default. | CURLOPT_TIMECONDITION. | ||||||
| .TP | .TP | ||||||
| .B CURLOPT_CUSTOMREQUEST | .B CURLOPT_CUSTOMREQUEST | ||||||
| Pass a pointer to a zero terminated string as parameter. It will be user | Pass a pointer to a zero terminated string as parameter. It will be user | ||||||
| @@ -615,10 +627,34 @@ Pass a long. If the value is non-zero, it tells curl to use the EPSV command | |||||||
| when doing passive FTP downloads (which is always does by default). Using EPSV | when doing passive FTP downloads (which is always does by default). Using EPSV | ||||||
| means that it will first attempt to use EPSV before using PASV, but if you | means that it will first attempt to use EPSV before using PASV, but if you | ||||||
| pass FALSE (zero) to this option, it will not try using EPSV, only plain PASV. | pass FALSE (zero) to this option, it will not try using EPSV, only plain PASV. | ||||||
|  | .TP | ||||||
|  | .B CURLOPT_DNS_CACHE_TIMEOUT | ||||||
|  | Pass a long, this sets the timeout in seconds. Name resolves will be kept in | ||||||
|  | memory for this number of seconds. Set to zero (0) to completely disable | ||||||
|  | caching, or set to -1 to make the cached entries remain forever. By default, | ||||||
|  | libcurl caches info for 60 seconds. (Added in libcurl 7.9.3) | ||||||
|  | .TP | ||||||
|  | .B CURLOPT_DNS_USE_GLOBAL_CACHE | ||||||
|  | Pass a long. If the value is non-zero, it tells curl to use a global DNS cache | ||||||
|  | that will survive between easy handles creations and deletions. This is not | ||||||
|  | thread-safe and this will use a global varible. (Added in libcurl 7.9.3) | ||||||
|  | .TP | ||||||
|  | .B CURLOPT_DEBUGFUNCTION | ||||||
|  | Function pointer that should match the following prototype: \fIint | ||||||
|  | curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP | ||||||
|  | This function will receive debug information if CURLOPT_VERBOSE is | ||||||
|  | enabled. The curl_infotype argument specifies what kind of information it | ||||||
|  | is. This funtion must return 0. | ||||||
|  | .TP | ||||||
|  | .B CURLOPT_DEBUGDATA | ||||||
|  | Pass a pointer to whatever you want passed in to your CURLOPT_DEBUGFUNCTION in | ||||||
|  | the last void * argument. This pointer is not used by libcurl, it is only | ||||||
|  | passed to the callback. | ||||||
| .PP | .PP | ||||||
| .SH RETURN VALUE | .SH RETURN VALUE | ||||||
| CURLE_OK (zero) means that the option was set properly, non-zero means an | CURLE_OK (zero) means that the option was set properly, non-zero means an | ||||||
| error occurred as \fI<curl/curl.h>\fP defines. | error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors.3\fP | ||||||
|  | man page for the full list with descriptions. | ||||||
| .SH "SEE ALSO" | .SH "SEE ALSO" | ||||||
| .BR curl_easy_init "(3), " curl_easy_cleanup "(3), " | .BR curl_easy_init "(3), " curl_easy_cleanup "(3), " | ||||||
| .SH BUGS | .SH BUGS | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| .\" nroff -man [file] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $Id$ | ||||||
| .\" | .\" | ||||||
| .TH curl_escape 3 "22 March 2001" "libcurl 7.7" "libcurl Manual" | .TH curl_escape 3 "6 March 2002" "libcurl 7.9" "libcurl Manual" | ||||||
| .SH NAME | .SH NAME | ||||||
| curl_escape - URL encodes the given string | curl_escape - URL encodes the given string | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| @@ -13,10 +13,8 @@ curl_escape - URL encodes the given string | |||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| This function will convert the given input string to an URL encoded string and | This function will convert the given input string to an URL encoded string and | ||||||
| return that as a new allocated string. All input characters that are not a-z, | return that as a new allocated string. All input characters that are not a-z, | ||||||
| A-Z or 0-9 will be converted to their "URL escaped" version. If a sequence of | A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a | ||||||
| %NN (where NN is a two-digit hexadecimal number) is found in the string to | two-digit hexadecimal number). | ||||||
| encode, that 3-letter combination will be copied to the output unmodifed, |  | ||||||
| assuming that it is an already encoded piece of data. |  | ||||||
| 
 | 
 | ||||||
| If the 'length' argument is set to 0, curl_escape() will use strlen() on the | If the 'length' argument is set to 0, curl_escape() will use strlen() on the | ||||||
| input 'url' string to find out the size. | input 'url' string to find out the size. | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| .\" nroff -man [file] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $Id$ | ||||||
| .\" | .\" | ||||||
| .TH curl_formadd 3 "29 October 2001" "libcurl 7.9.1" "libcurl Manual" | .TH curl_formadd 3 "1 Match 2002" "libcurl 7.9.1" "libcurl Manual" | ||||||
| .SH NAME | .SH NAME | ||||||
| curl_formadd - add a section to a multipart/formdata HTTP POST | curl_formadd - add a section to a multipart/formdata HTTP POST | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| @@ -87,8 +87,8 @@ Returns non-zero if an error occurs. | |||||||
| .SH EXAMPLE | .SH EXAMPLE | ||||||
| .nf | .nf | ||||||
| 
 | 
 | ||||||
|  HttpPost* post = NULL; |  struct HttpPost* post = NULL; | ||||||
|  HttpPost* last = NULL; |  struct HttpPost* last = NULL; | ||||||
|  char namebuffer[] = "name buffer"; |  char namebuffer[] = "name buffer"; | ||||||
|  long namelength = strlen(namebuffer); |  long namelength = strlen(namebuffer); | ||||||
|  char buffer[] = "test buffer"; |  char buffer[] = "test buffer"; | ||||||
							
								
								
									
										20
									
								
								docs/libcurl/curl_multi_add_handle.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								docs/libcurl/curl_multi_add_handle.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_add_handle 3 "4 March 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_add_handle - add an easy handle to a multi session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle); | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | Adds a standard easy handle to the multi stack. This will make this multi | ||||||
|  | handle control the specified easy handle. | ||||||
|  |  | ||||||
|  | When an easy handle has been added to a multi stack, you can not and you must | ||||||
|  | not use curl_easy_perform() on that handle! | ||||||
|  | .SH RETURN VALUE | ||||||
|  | CURLMcode type, general libcurl multi interface error code. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_cleanup "(3)," curl_multi_init "(3)" | ||||||
							
								
								
									
										18
									
								
								docs/libcurl/curl_multi_cleanup.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								docs/libcurl/curl_multi_cleanup.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_cleanup 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_cleanup - close down a multi session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | .B #include <curl/curl.h> | ||||||
|  | .sp | ||||||
|  | .BI "CURLMcode curl_multi_cleanup( CURLM *multi_handle );" | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | Cleans up and removes a whole multi stack. It does not free or touch any | ||||||
|  | individual easy handles in any way - they still need to be closed | ||||||
|  | individually, using the usual curl_easy_cleanup() way. | ||||||
|  | .SH RETURN VALUE | ||||||
|  | CURLMcode type, general libcurl multi interface error code. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_init "(3)," curl_easy_cleanup "(3)," curl_easy_init "(3)" | ||||||
							
								
								
									
										27
									
								
								docs/libcurl/curl_multi_fdset.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								docs/libcurl/curl_multi_fdset.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_fdset 3 "3 May 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_fdset - add an easy handle to a multi session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | CURLMcode curl_multi_fdset(CURLM *multi_handle, | ||||||
|  |                            fd_set *read_fd_set, | ||||||
|  |                            fd_set *write_fd_set, | ||||||
|  |                            fd_set *exc_fd_set, | ||||||
|  |                            int *max_fd); | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | This function extracts file descriptor information from a given multi_handle. | ||||||
|  | libcurl returns its fd_set sets. The application can use these to select() or | ||||||
|  | poll() on. The curl_multi_perform() function should be called as soon as one | ||||||
|  | of them are ready to be read from or written to. | ||||||
|  |  | ||||||
|  | NOTE that once this call is made, you must not remove the sets you point to, | ||||||
|  | as libcurl will need to be able to read them. It needs them after select() | ||||||
|  | calls, to know if certain sockets are readable or writable. | ||||||
|  | .SH RETURN VALUE | ||||||
|  | CURLMcode type, general libcurl multi interface error code. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_cleanup "(3)," curl_multi_init "(3)" | ||||||
							
								
								
									
										35
									
								
								docs/libcurl/curl_multi_info_read.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								docs/libcurl/curl_multi_info_read.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_info_read 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_info_read - read multi stack informationals | ||||||
|  | .SH SYNOPSIS | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | CURLMsg *curl_multi_info_read( CURLM *multi_handle, | ||||||
|  |                                int *msgs_in_queue); | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | Ask the multi handle if there's any messages/informationals from the | ||||||
|  | individual transfers. Messages include informationals such as an error code | ||||||
|  | from the transfer or just the fact that a transfer is completed. More details | ||||||
|  | on these should be written down as well. | ||||||
|  |  | ||||||
|  | Repeated calls to this function will return a new struct each time, until a | ||||||
|  | special "end of msgs" struct is returned as a signal that there is no more to | ||||||
|  | get at this point. The integer pointed to with \fImsgs_in_queue\fP will | ||||||
|  | contain the number of remaining messages after this function was called. | ||||||
|  |  | ||||||
|  | The data the returned pointer points to will not survive calling | ||||||
|  | curl_multi_cleanup(). | ||||||
|  |  | ||||||
|  | The 'CURLMsg' struct is very simple and only contain very basic informations. | ||||||
|  | If more involved information is wanted, the particular "easy handle" in | ||||||
|  | present in that struct and can thus be used in subsequent regular | ||||||
|  | curl_easy_getinfo() calls (or similar). | ||||||
|  | .SH "RETURN VALUE" | ||||||
|  | A pointer to a filled-in struct, or NULL if it failed or ran out of | ||||||
|  | structs. It also writes the number of messages left in the queue (after this | ||||||
|  | read) in the integer the second argument points to. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_cleanup "(3)," curl_multi_init "(3)," curl_multi_perform "(3)" | ||||||
							
								
								
									
										22
									
								
								docs/libcurl/curl_multi_init.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								docs/libcurl/curl_multi_init.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_init 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_init - Start a multi session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | .B #include <curl/curl.h> | ||||||
|  | .sp | ||||||
|  | .BI "CURLM *curl_multi_init( );" | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | This function returns a CURLM handle to be used as input to all the other | ||||||
|  | multi-functions, sometimes refered to as a multi handle on some places in the | ||||||
|  | documentation. This init call MUST have a corresponding call to | ||||||
|  | \fIcurl_multi_cleanup\fP when the operation is complete. | ||||||
|  | .SH RETURN VALUE | ||||||
|  | If this function returns NULL, something went wrong and you cannot use the | ||||||
|  | other curl functions. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_cleanup "(3)," curl_global_init "(3)," curl_easy_init "(3)" | ||||||
|  | .SH BUGS | ||||||
|  | Surely there are some, you tell me! | ||||||
							
								
								
									
										30
									
								
								docs/libcurl/curl_multi_perform.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								docs/libcurl/curl_multi_perform.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_perform 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_perform - add an easy handle to a multi session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles); | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | When the app thinks there's data available for the multi_handle, it should | ||||||
|  | call this function to read/write whatever there is to read or write right | ||||||
|  | now. curl_multi_perform() returns as soon as the reads/writes are done. This | ||||||
|  | function does not require that there actually is any data available for | ||||||
|  | reading or that data can be written, it can be called just in case. It will | ||||||
|  | write the number of handles that still transfer data in the second argument's | ||||||
|  | integer-pointer. | ||||||
|  | .SH "RETURN VALUE" | ||||||
|  | CURLMcode type, general libcurl multi interface error code. | ||||||
|  |  | ||||||
|  | NOTE that this only returns errors etc regarding the whole multi stack. There | ||||||
|  | might still have occurred problems on invidual transfers even when this | ||||||
|  | function returns OK. | ||||||
|  | .SH "TYPICAL USAGE" | ||||||
|  | Most application will use \fIcurl_multi_fdset\fP to get the multi_handle's | ||||||
|  | file descriptors, then it'll wait for action on them using select() and as | ||||||
|  | soon as one or more of them are ready, \fIcurl_multi_perform\fP gets called. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_cleanup "(3)," curl_multi_init "(3)" | ||||||
							
								
								
									
										20
									
								
								docs/libcurl/curl_multi_remove_handle.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								docs/libcurl/curl_multi_remove_handle.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH curl_multi_remove_handle 3 "6 March 2002" "libcurl 7.9.5" "libcurl Manual" | ||||||
|  | .SH NAME | ||||||
|  | curl_multi_remove_handle - add an easy handle to a multi session | ||||||
|  | .SH SYNOPSIS | ||||||
|  | #include <curl/curl.h> | ||||||
|  |  | ||||||
|  | CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle); | ||||||
|  | .ad | ||||||
|  | .SH DESCRIPTION | ||||||
|  | Removes a given easy_handle from the multi_handle. This will make the | ||||||
|  | specified easy handle be removed from this multi handle's control. | ||||||
|  |  | ||||||
|  | When the easy handle has been removed from a multi stack, it is again | ||||||
|  | perfectly legal to invoke \fIcurl_easy_perform()\fP on this easy handle. | ||||||
|  | .SH RETURN VALUE | ||||||
|  | CURLMcode type, general libcurl multi interface error code. | ||||||
|  | .SH "SEE ALSO" | ||||||
|  | .BR curl_multi_cleanup "(3)," curl_multi_init "(3)" | ||||||
| @@ -14,7 +14,7 @@ curl_unescape - URL decodes the given string | |||||||
| This function will convert the given URL encoded input string to a "plain | This function will convert the given URL encoded input string to a "plain | ||||||
| string" and return that as a new allocated string. All input characters that | string" and return that as a new allocated string. All input characters that | ||||||
| are URL encoded (%XX where XX is a two-digit hexadecimal number, or +) will be | are URL encoded (%XX where XX is a two-digit hexadecimal number, or +) will be | ||||||
| converted to their plain text versions (up to a ? letter, no letters to the | converted to their plain text versions (up to a ? letter, no + letters to the | ||||||
| right of a ? letter will be converted). | right of a ? letter will be converted). | ||||||
| 
 | 
 | ||||||
| If the 'length' argument is set to 0, curl_unescape() will use strlen() on the | If the 'length' argument is set to 0, curl_unescape() will use strlen() on the | ||||||
| @@ -34,5 +34,15 @@ HTML> | |||||||
| <P><A HREF="curl_strnequal.html">curl_strnequal.html</A> | <P><A HREF="curl_strnequal.html">curl_strnequal.html</A> | ||||||
| <P><A HREF="curl_unescape.html">curl_unescape.html</A> | <P><A HREF="curl_unescape.html">curl_unescape.html</A> | ||||||
| <P><A HREF="curl_version.html">curl_version.html</A> | <P><A HREF="curl_version.html">curl_version.html</A> | ||||||
|  | <hr> | ||||||
|  | <p><a href="curl_multi_add_handle.html">curl_multi_add_handle.html</a> | ||||||
|  | <p><a href="curl_multi_cleanup.html">curl_multi_cleanup.html</a> | ||||||
|  | <p><a href="curl_multi_fdset.html">curl_multi_fdset.html</a> | ||||||
|  | <p><a href="curl_multi_info_read.html">curl_multi_info_read.html</a> | ||||||
|  | <p><a href="curl_multi_init.html">curl_multi_init.html</a> | ||||||
|  | <p><a href="curl_multi_perform.html">curl_multi_perform.html</a> | ||||||
|  | <p><a href="curl_multi_remove_handle.html">curl_multi_remove_handle.html</a> | ||||||
|  | <p><a href="libcurl-multi.html">libcurl-multi.html</a> | ||||||
|  | 
 | ||||||
| </BODY> | </BODY> | ||||||
| </HTML> | </HTML> | ||||||
							
								
								
									
										240
									
								
								docs/libcurl/libcurl-errors.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								docs/libcurl/libcurl-errors.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | |||||||
|  | .\" You can view this file with: | ||||||
|  | .\" nroff -man [file] | ||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH libcurl-errors 3 "10 April 2002" "libcurl 7.9.6" "libcurl errors" | ||||||
|  | .SH NAME | ||||||
|  | error codes in libcurl | ||||||
|  | .SH DESCRIPTION | ||||||
|  | This man page includes most, if not all, available error codes in libcurl. | ||||||
|  | Why they occur and possibly what you can do to fix the problem. | ||||||
|  | .SH "CURLcode" | ||||||
|  | Almost all "easy" interface functions return a CURLcode error code. No matter | ||||||
|  | what, using \fICURLOPT_ERRORBUFFER\fP is a good idea as it will give you a | ||||||
|  | human readable error string that may offer more details about the error cause | ||||||
|  | than just the error code does. | ||||||
|  |  | ||||||
|  | This man page is meant to describe libcurl 7.9.6 and later. Earlier versions | ||||||
|  | might have had quirks not mentioned here. | ||||||
|  |  | ||||||
|  | CURLcode is one of the following: | ||||||
|  | .RS 1 | ||||||
|  | .TP 5 | ||||||
|  | .B CURLE_OK (0) | ||||||
|  | All fine. Proceed as usual. | ||||||
|  | .TP | ||||||
|  | .B CURLE_UNSUPPORTED_PROTOCOL (1) | ||||||
|  | The URL you passed to libcurl used a protocol that this libcurl does not | ||||||
|  | support. The support might be a compile-time option that you didn't use, it | ||||||
|  | can be a misspelled protocol string or just a protocol libcurl has no code | ||||||
|  | for. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FAILED_INIT (2) | ||||||
|  | Very early initialization code failed. This is likely to be an internal error | ||||||
|  | or problem. | ||||||
|  | .TP | ||||||
|  | .B CURLE_URL_MALFORMAT (3) | ||||||
|  | The URL was not properly formatted. | ||||||
|  | .TP | ||||||
|  | .B CURLE_URL_MALFORMAT_USER (4) | ||||||
|  | URL user malformatted. The user-part of the URL syntax was not correct. | ||||||
|  | .TP | ||||||
|  | .B CURLE_COULDNT_RESOLVE_PROXY (5) | ||||||
|  | Couldn't resolve proxy. The given proxy host could not be resolved. | ||||||
|  | .TP | ||||||
|  | .B CURLE_COULDNT_RESOLVE_HOST (6) | ||||||
|  | Couldn't resolve host. The given remote host was not resolved. | ||||||
|  | .TP | ||||||
|  | .B CURLE_COULDNT_CONNECT (7) | ||||||
|  | Failed to connect() to host or proxy. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_WEIRD_SERVER_REPLY (8) | ||||||
|  | After connecting to a FTP server, libcurl expects to get a certain reply back. | ||||||
|  | This error code implies that it god a strange or bad reply. The given remote | ||||||
|  | server is probably not an OK FTP server. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_ACCESS_DENIED (9) | ||||||
|  | We were denied access when trying to login to an FTP server or when trying to | ||||||
|  | change working directory to the one given in the URL. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_USER_PASSWORD_INCORRECT (10) | ||||||
|  | The username and/or the password were incorrect when trying to login to an FTP | ||||||
|  | server. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_WEIRD_PASS_REPLY (11) | ||||||
|  | After having sent the FTP password to the server, libcurl expects a proper | ||||||
|  | reply. This error code indicates that an unexpected code was returned. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_WEIRD_USER_REPLY (12) | ||||||
|  | After having sent user name to the FTP server, libcurl expects a proper | ||||||
|  | reply. This error code indicates that an unexpected code was returned. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_WEIRD_PASV_REPLY (13) | ||||||
|  | libcurl failed to get a sensible result back from the server as a response to | ||||||
|  | either a PASV or a EPSV command. The server is flawed. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_WEIRD_227_FORMAT (14) | ||||||
|  | FTP servers return a 227-line as a response to a PASV command. If libcurl | ||||||
|  | fails to parse that line, this return code is passed back. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_CANT_GET_HOST (15) | ||||||
|  | An internal failure to lookup the host used for the new connection. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_CANT_RECONNECT (16) | ||||||
|  | A bad return code on either PASV or EPSV was sent by the FTP server, | ||||||
|  | preventing libcurl from being able to continue. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_COULDNT_SET_BINARY (17) | ||||||
|  | Received an error when trying to set the transfer mode to binary. | ||||||
|  | .TP | ||||||
|  | .B CURLE_PARTIAL_FILE (18) | ||||||
|  | A file transfer was shorter or larger than expected. This happens when the | ||||||
|  | server first reports an expected transfer size, and then delivers data that | ||||||
|  | doesn't match the previously given size. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_COULDNT_RETR_FILE (19) | ||||||
|  | This was either a weird reply to a 'RETR' command or a zero byte transfer | ||||||
|  | complete. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_WRITE_ERROR (20) | ||||||
|  | After a completed file transfer, the FTP server did not respond a proper | ||||||
|  | \"transfer successful\" code. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_QUOTE_ERROR (21) | ||||||
|  | When sending custom "QUOTE" commands to the remote server, one of the commands | ||||||
|  | returned an error code that was 400 or higher. | ||||||
|  | .TP | ||||||
|  | .B CURLE_HTTP_NOT_FOUND (22) | ||||||
|  | This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server | ||||||
|  | returns an error code that is >= 400. | ||||||
|  | .TP | ||||||
|  | .B CURLE_WRITE_ERROR (23) | ||||||
|  | An error occurred when writing received data to a local file, or an error was | ||||||
|  | returned to libcurl from a write callback. | ||||||
|  | .TP | ||||||
|  | .B CURLE_MALFORMAT_USER (24) | ||||||
|  | Malformat user. User name badly specified. *Not currently used* | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_COULDNT_STOR_FILE (25) | ||||||
|  | FTP couldn't STOR file. The server denied the STOR operation. The error buffer | ||||||
|  | usually contains the server's explanation to this. | ||||||
|  | .TP | ||||||
|  | .B CURLE_READ_ERROR (26) | ||||||
|  | There was a problem reading a local file or an error returned by the read | ||||||
|  | callback. | ||||||
|  | .TP | ||||||
|  | .B CURLE_OUT_OF_MEMORY (27) | ||||||
|  | Out of memory. A memory allocation request failed. This is serious badness and | ||||||
|  | things are severly screwed up if this ever occur. | ||||||
|  | .TP | ||||||
|  | .B CURLE_OPERATION_TIMEOUTED (28) | ||||||
|  | Operation timeout. The specified time-out period was reached according to the | ||||||
|  | conditions. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_COULDNT_SET_ASCII (29) | ||||||
|  | libcurl failed to set ASCII transfer type (TYPE A). | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_PORT_FAILED (30) | ||||||
|  | The FTP PORT command returned error. This mostly happen when you haven't | ||||||
|  | specified a good enough address for libcurl to use. See \fICURLOPT_FTPPORT\fP. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_COULDNT_USE_REST (31) | ||||||
|  | The FTP REST command returned error. This should never happen if the server is | ||||||
|  | sane. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_COULDNT_GET_SIZE (32) | ||||||
|  | The FTP SIZE command returned errror. SIZE is not a kosher FTP command, it is | ||||||
|  | an extension and not all servers support it. This is not a surprising error. | ||||||
|  | .TP | ||||||
|  | .B CURLE_HTTP_RANGE_ERROR (33) | ||||||
|  | The HTTP server does not support or accept range requests. | ||||||
|  | .TP | ||||||
|  | .B CURLE_HTTP_POST_ERROR (34) | ||||||
|  | This is an odd error that mainly occurs due to internal confusion. | ||||||
|  | .TP | ||||||
|  | .B CURLE_SSL_CONNECT_ERROR (35) | ||||||
|  | A problem occured somewhere in the SSL/TLS handshake. You really want the | ||||||
|  | error buffer and read the message there as it pinpoints the problem slightly | ||||||
|  | more. Could be certificates (file formats, paths, permissions), passwords, and | ||||||
|  | others. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FTP_BAD_DOWNLOAD_RESUME (36) | ||||||
|  | Attempting FTP resume beyond file size. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FILE_COULDNT_READ_FILE (37) | ||||||
|  | A file given with FILE:// couldn't be opened. Most likely because the file | ||||||
|  | path doesn't identify an existing file. Did you check file permissions? | ||||||
|  | .TP | ||||||
|  | .B CURLE_LDAP_CANNOT_BIND (38) | ||||||
|  | LDAP cannot bind. LDAP bind operation failed. | ||||||
|  | .TP | ||||||
|  | .B CURLE_LDAP_SEARCH_FAILED (39) | ||||||
|  | LDAP search failed. | ||||||
|  | .TP | ||||||
|  | .B CURLE_LIBRARY_NOT_FOUND (40) | ||||||
|  | Library not found. The LDAP library was not found. | ||||||
|  | .TP | ||||||
|  | .B CURLE_FUNCTION_NOT_FOUND (41) | ||||||
|  | Function not found. A required LDAP function was not found. | ||||||
|  | .TP | ||||||
|  | .B CURLE_ABORTED_BY_CALLBACK (42) | ||||||
|  | Aborted by callback. A callback returned "abort" to libcurl. | ||||||
|  | .TP | ||||||
|  | .B CURLE_BAD_FUNCTION_ARGUMENT (43) | ||||||
|  | Internal error. A function was called with a bad parameter. | ||||||
|  | .TP | ||||||
|  | .B CURLE_BAD_CALLING_ORDER (44) | ||||||
|  | Internal error. A function was called in a bad order. | ||||||
|  | .TP | ||||||
|  | .B CURLE_HTTP_PORT_FAILED (45) | ||||||
|  | Interface error. A specified outgoing interface could not be used. Set which | ||||||
|  | interface to use for outgoing connections' source IP address with | ||||||
|  | CURLOPT_INTERFACE. | ||||||
|  | .TP | ||||||
|  | .B CURLE_BAD_PASSWORD_ENTERED (46) | ||||||
|  | Bad password entered. An error was signaled when the password was | ||||||
|  | entered. This can also be the result of a "bad password" returned from a | ||||||
|  | specified password callback. | ||||||
|  | .TP | ||||||
|  | .B CURLE_TOO_MANY_REDIRECTS (47) | ||||||
|  | Too many redirects. When following redirects, libcurl hit the maximum amount. | ||||||
|  | Set your limit with CURLOPT_MAXREDIRS. | ||||||
|  | .TP | ||||||
|  | .B CURLE_UNKNOWN_TELNET_OPTION (48) | ||||||
|  | An option set with CURLOPT_TELNETOPTIONS was not recognized/known. Refer to | ||||||
|  | the appropriate documentation. | ||||||
|  | .TP | ||||||
|  | .B CURLE_TELNET_OPTION_SYNTAX (49) | ||||||
|  | A telnet option string was Illegally formatted. | ||||||
|  | .TP | ||||||
|  | .B CURLE_OBSOLETE (50) | ||||||
|  | This is not an error. This used to be another error code in an old libcurl | ||||||
|  | version and is currently unused. | ||||||
|  | .TP | ||||||
|  | .B CURLE_SSL_PEER_CERTIFICATE (51) | ||||||
|  | The remote server's SSL certificate was deemed not OK. | ||||||
|  | .TP | ||||||
|  | .B CURLE_GOT_NOTHING (52) | ||||||
|  | Nothing was returned from the server, and under the circumstances, getting | ||||||
|  | nothing is considered an error. | ||||||
|  | .TP | ||||||
|  | .B CURLE_SSL_ENGINE_NOTFOUND (53) | ||||||
|  | The specified crypto engine wasn't found. | ||||||
|  | .TP | ||||||
|  | .B CURLE_SSL_ENGINE_SETFAILED (54) | ||||||
|  | Failed setting the selected SSL crypto engine as default! | ||||||
|  | .TP | ||||||
|  | .B CURLE_SEND_ERROR (55) | ||||||
|  | Failed sending network data. | ||||||
|  | .TP | ||||||
|  | .B CURLE_RECV_ERROR (56) | ||||||
|  | Failure with receiving network data. | ||||||
|  | .TP | ||||||
|  | .B CURL_LAST | ||||||
|  | This is not an error, but in the curl/curl.h file this can be used to know how | ||||||
|  | many existing error codes there are. | ||||||
|  | .RE | ||||||
|  |  | ||||||
|  | .SH "CURLMcode" | ||||||
|  | This is the generic return code used by functions in the libcurl multi | ||||||
|  | interface. | ||||||
							
								
								
									
										85
									
								
								docs/libcurl/libcurl-multi.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								docs/libcurl/libcurl-multi.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | .\" You can view this file with: | ||||||
|  | .\" nroff -man [file] | ||||||
|  | .\" $Id$ | ||||||
|  | .\" | ||||||
|  | .TH libcurl-multi 5 "20 March 2001" "libcurl 7.9.5" "libcurl multi interface" | ||||||
|  | .SH NAME | ||||||
|  | libcurl-multi \- how to use the multi interface | ||||||
|  | .SH DESCRIPTION | ||||||
|  | This is an overview on how to use the libcurl multi interface in your C | ||||||
|  | programs. There are specific man pages for each function mentioned in | ||||||
|  | here. There's also the libcurl-the-guide document for a complete tutorial to | ||||||
|  | programming with libcurl and the \fIlibcurl(3)\fP man page for an overview of | ||||||
|  | the libcurl easy interface. | ||||||
|  |  | ||||||
|  | All functions in the multi interface are prefixed with curl_multi. | ||||||
|  | .SH "PLEASE NOTICE" | ||||||
|  | The multi interface is a rather new member of the libcurl family. It has not | ||||||
|  | yet been very widely used. It may still be a few more bugs lurking in there | ||||||
|  | than we are used to. That said, it might also just work in every aspect you | ||||||
|  | try it. Please report all bugs and oddities you see. | ||||||
|  | .SH "OBJECTIVES" | ||||||
|  | The multi interface introduces several new abilities that the easy interface | ||||||
|  | refuses to offer. They are mainly: | ||||||
|  |  | ||||||
|  | 1. Enable a "pull" interface. The application that uses libcurl decides where | ||||||
|  | and when to ask libcurl to get/send data. | ||||||
|  |  | ||||||
|  | 2. Enable multiple simultaneous transfers in the same thread without making it | ||||||
|  | complicated for the application. | ||||||
|  |  | ||||||
|  | 3. Enable the application to select() on its own file descriptors and curl's | ||||||
|  | file descriptors simultaneous easily. | ||||||
|  | .SH "ONE MULTI HANDLE MANY EASY HANDLES" | ||||||
|  | To use the multi interface, you must first create a 'multi handle' with | ||||||
|  | \fIcurl_multi_init\fP. This handle is then used as input to all further | ||||||
|  | curl_multi_* functions. | ||||||
|  |  | ||||||
|  | Each single transfer is built up with an easy handle. You must create them, | ||||||
|  | and setup the appropriate options for each easy handle, as outlined in the | ||||||
|  | \fIlibcurl(3)\fP man page. | ||||||
|  |  | ||||||
|  | When the easy handle is setup for a transfer, then instead of using | ||||||
|  | \fIcurl_easy_perform\fP (as when using the easy interface for transfers), you | ||||||
|  | should instead add the easy handle to the multi handle using | ||||||
|  | \fIcurl_easy_add_handl\fP. The multi handle is sometimes referred to as a | ||||||
|  | \'multi stack\' because of the fact that it may hold a large amount of easy | ||||||
|  | handles. | ||||||
|  |  | ||||||
|  | Should you change your mind, the easy handle is again removed from the multi | ||||||
|  | stack using \fIcurl_multi_remove_handle\fP. Once removed from the multi | ||||||
|  | handle, you can again use other easy interface functions like | ||||||
|  | curl_easy_perform or whatever you think is necessary. | ||||||
|  |  | ||||||
|  | Adding the easy handles to the multi handle does not start any | ||||||
|  | transfer. Remember that one of the main ideas with this interface is to let | ||||||
|  | your application drive. You drive the transfers by invoking | ||||||
|  | \fIcurl_multi_perform\fP. libcurl will then transfer data if there is anything | ||||||
|  | available to transfer. It'll use the callbacks and everything else you have | ||||||
|  | setup in the individual easy handles. It'll transfer data on all current | ||||||
|  | transfers in the multi stack that are ready to transfer anything. It may be | ||||||
|  | all, it may be none. | ||||||
|  |  | ||||||
|  | Your application can acquire knowledge from libcurl when it would like to get | ||||||
|  | invoked to transfer data, so that you don't have to busy-loop and call that | ||||||
|  | \fIcurl_multi_perform\fP like a mad man! \fIcurl_multi_fdset\fP offers an | ||||||
|  | interface using which you can extract fd_sets from libcurl to use in select() | ||||||
|  | or poll() calls in order to get to know when the transfers in the multi stack | ||||||
|  | might need attention. This also makes it very easy for your program to wait | ||||||
|  | for input on your own private file descriptors at the same time or perhaps | ||||||
|  | timeout every now and then, should you want that. | ||||||
|  |  | ||||||
|  | \fIcurl_multi_perform\fP stores the number of still running transfers in one | ||||||
|  | of its input arguments, and by reading that you can figure out when all the | ||||||
|  | transfers in the multi handles are done. 'done' does not mean successful. One | ||||||
|  | or more of the transfers may have failed. | ||||||
|  |  | ||||||
|  | To get information about completed transfers, to figure out success or not and | ||||||
|  | similar, \fIcurl_multi_info_read\fP should be called. It can return a message | ||||||
|  | about a current or previous transfer. Repeated invokes of the function get | ||||||
|  | more messages until the message queue is empty. | ||||||
|  |  | ||||||
|  | When all transfers in the multi stack are done, cleanup the multi handle with | ||||||
|  | \fIcurl_multi_cleanup\fP. Be careful and please note that you \fBMUST\fP | ||||||
|  | invoke separate \fIcurl_easy_cleanup\fP calls on every single easy handle to | ||||||
|  | clean them up properly. | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| .\" nroff -man [file] | .\" nroff -man [file] | ||||||
| .\" $Id$ | .\" $Id$ | ||||||
| .\" | .\" | ||||||
| .TH libcurl 5 "14 August 2001" "libcurl 7.8.1" "libcurl overview" | .TH libcurl 3 "19 March 2002" "libcurl 7.9.6" "libcurl overview" | ||||||
| .SH NAME | .SH NAME | ||||||
| libcurl \- client-side URL transfers | libcurl \- client-side URL transfers | ||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| @@ -11,17 +11,18 @@ specific man pages for each function mentioned in here. There's also the | |||||||
| libcurl-the-guide document for a complete tutorial to programming with | libcurl-the-guide document for a complete tutorial to programming with | ||||||
| libcurl. | libcurl. | ||||||
| 
 | 
 | ||||||
| libcurl can also be used directly from within your Java, PHP, Perl, Ruby or | There are a dozen custom bindings that bring libcurl access to your favourite | ||||||
| Tcl programs as well, look elsewhere for documentation on this! | language. Look elsewhere for documentation on those. | ||||||
| 
 | 
 | ||||||
| All applications that use libcurl should call \fIcurl_global_init()\fP exactly | All applications that use libcurl should call \fIcurl_global_init()\fP exactly | ||||||
| once before any libcurl function can be used. After all usage of libcurl is | once before any libcurl function can be used. After all usage of libcurl is | ||||||
| complete, it \fBmust\fP call \fIcurl_global_cleanup()\fP. In between those two | complete, it \fBmust\fP call \fIcurl_global_cleanup()\fP. In between those two | ||||||
| calls, you can use libcurl as described below. | calls, you can use libcurl as described below. | ||||||
| 
 | 
 | ||||||
| When using libcurl you init your session and get a handle, which you use as | When using libcurl's "easy" interface you init your session and get a handle, | ||||||
| input to the following interface functions you use. Use \fIcurl_easy_init()\fP | which you use as input to the easy interface functions you use. Use | ||||||
| to get the handle. | \fIcurl_easy_init()\fP to get the handle. There is also the so called "multi" | ||||||
|  | interface, try the \fIlibcurl-multi(3)\fP man page for an overview of that. | ||||||
| 
 | 
 | ||||||
| You continue by setting all the options you want in the upcoming transfer, | You continue by setting all the options you want in the upcoming transfer, | ||||||
| most important among them is the URL itself (you can't transfer anything | most important among them is the URL itself (you can't transfer anything | ||||||
| @@ -75,9 +76,8 @@ portable case insensitive string comparisons | |||||||
| .RE | .RE | ||||||
| 
 | 
 | ||||||
| .SH "LINKING WITH LIBCURL" | .SH "LINKING WITH LIBCURL" | ||||||
| Starting with 7.7.2 (on unix-like machines), there's a tool named curl-config | On unix-like machines, there's a tool named curl-config that gets installed | ||||||
| that gets installed with the rest of the curl stuff when 'make install' is | with the rest of the curl stuff when 'make install' is performed. | ||||||
| performed. |  | ||||||
| 
 | 
 | ||||||
| curl-config is added to make it easier for applications to link with libcurl | curl-config is added to make it easier for applications to link with libcurl | ||||||
| and developers to learn about libcurl and how to use it. | and developers to learn about libcurl and how to use it. | ||||||
| @@ -97,36 +97,24 @@ Only use documented functions and functionality! | |||||||
| libcurl works | libcurl works | ||||||
| .B exactly | .B exactly | ||||||
| the same, on any of the platforms it compiles and builds on. | the same, on any of the platforms it compiles and builds on. | ||||||
| 
 |  | ||||||
| There's only one caution, and that is the win32 platform that may(*) require |  | ||||||
| you to init the winsock stuff before you use the libcurl functions. Details on |  | ||||||
| this are noted on the curl_easy_init() man page. |  | ||||||
| 
 |  | ||||||
| (*) = it appears as if users of the cygwin environment get this done |  | ||||||
| automatically, also libcurl 7.8.1 and later can handle this for you. |  | ||||||
| .SH "THREADS" | .SH "THREADS" | ||||||
| Never ever call curl-functions simultaneously using the same handle from | Never ever call curl-functions simultaneously using the same handle from | ||||||
| several threads. libcurl is thread-safe and can be used in any number of | several threads. libcurl is thread-safe and can be used in any number of | ||||||
| threads, but you must use separate curl handles if you want to use libcurl in | threads, but you must use separate curl handles if you want to use libcurl in | ||||||
| more than one thread simultaneously. | more than one thread simultaneously. | ||||||
| .SH "PERSISTANT CONNECTIONS" | .SH "PERSISTANT CONNECTIONS" | ||||||
| With libcurl 7.7, persistant connections were added. Persistant connections | Persistent connections means that libcurl can re-use the same connection for | ||||||
| means that libcurl can re-use the same connection for several transfers, if | several transfers, if the conditions are right. | ||||||
| the conditions are right. |  | ||||||
| 
 | 
 | ||||||
| libcurl will *always* attempt to use persistant connections. Whenever you use | libcurl will *always* attempt to use persistent connections. Whenever you use | ||||||
| curl_easy_perform(), libcurl will attempt to use an existing connection to do | curl_easy_perform(), libcurl will attempt to use an existing connection to do | ||||||
| the transfer, and if none exists it'll open a new one that will be subject | the transfer, and if none exists it'll open a new one that will be subject for | ||||||
| for re-use on a possible following call to curl_easy_perform(). | re-use on a possible following call to curl_easy_perform(). | ||||||
| 
 | 
 | ||||||
| To allow libcurl to take full advantage of persistant connections, you should | To allow libcurl to take full advantage of persistent connections, you should | ||||||
| do as many of your file transfers as possible using the same curl | do as many of your file transfers as possible using the same curl handle. When | ||||||
| handle. When you call curl_easy_cleanup(), all the possibly open connections | you call curl_easy_cleanup(), all the possibly open connections held by | ||||||
| held by libcurl will be closed and forgotten. | libcurl will be closed and forgotten. | ||||||
| 
 | 
 | ||||||
| Note that the options set with curl_easy_setopt() will be used in on every | Note that the options set with curl_easy_setopt() will be used in on every | ||||||
| repeat curl_easy_perform() call | repeat curl_easy_perform() call | ||||||
| .SH "COMPATIBILITY WITH OLDER LIBCURLS" |  | ||||||
| Repeated curl_easy_perform() calls on the same handle were not supported in |  | ||||||
| pre-7.7 versions, and caused confusion and undefined behaviour. |  | ||||||
| 
 |  | ||||||
| @@ -3,5 +3,6 @@ pkginclude_HEADERS = \ | |||||||
| 	easy.h \ | 	easy.h \ | ||||||
| 	mprintf.h \ | 	mprintf.h \ | ||||||
| 	stdcheaders.h \ | 	stdcheaders.h \ | ||||||
| 	types.h | 	types.h \ | ||||||
|  | 	multi.h | ||||||
| pkgincludedir= $(includedir)/curl | pkgincludedir= $(includedir)/curl | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -55,16 +55,20 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| struct HttpPost { | /* stupid #define trick to preserve functionality with older code, but | ||||||
|   struct HttpPost *next; /* next entry in the list */ |    making it use our name space for the future */ | ||||||
|  | #define HttpPost curl_httppost | ||||||
|  |  | ||||||
|  | struct curl_httppost { | ||||||
|  |   struct curl_httppost *next; /* next entry in the list */ | ||||||
|   char *name;     /* pointer to allocated name */ |   char *name;     /* pointer to allocated name */ | ||||||
|   long namelength; /* length of name length */ |   long namelength; /* length of name length */ | ||||||
|   char *contents; /* pointer to allocated data contents */ |   char *contents; /* pointer to allocated data contents */ | ||||||
|   long contentslength; /* length of contents field */ |   long contentslength; /* length of contents field */ | ||||||
|   char *contenttype; /* Content-Type */ |   char *contenttype; /* Content-Type */ | ||||||
|   struct curl_slist* contentheader; /* list of extra headers for this form */ |   struct curl_slist* contentheader; /* list of extra headers for this form */ | ||||||
|   struct HttpPost *more; /* if one field name has more than one file, this |   struct curl_httppost *more; /* if one field name has more than one file, this | ||||||
| 			    link should link to following files */ |                                  link should link to following files */ | ||||||
|   long flags;     /* as defined below */ |   long flags;     /* as defined below */ | ||||||
| #define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ | #define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ | ||||||
| #define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ | #define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ | ||||||
| @@ -72,13 +76,17 @@ struct HttpPost { | |||||||
|                                    do not free in formfree */ |                                    do not free in formfree */ | ||||||
| #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer | #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer | ||||||
|                                        do not free in formfree */ |                                        do not free in formfree */ | ||||||
|  |   char *showfilename; /* The file name to show. If not set, the actual | ||||||
|  |                          file name will be used (if this is a file part) */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef int (*curl_progress_callback)(void *clientp, | typedef int (*curl_progress_callback)(void *clientp, | ||||||
|                                       size_t dltotal, |                                       double dltotal, | ||||||
|                                       size_t dlnow, |                                       double dlnow, | ||||||
|                                       size_t ultotal, |                                       double ultotal, | ||||||
|                                       size_t ulnow); |                                       double ulnow); | ||||||
|  |  | ||||||
|  | #define CURL_MAX_WRITE_SIZE 20480 | ||||||
|  |  | ||||||
| typedef size_t (*curl_write_callback)(char *buffer, | typedef size_t (*curl_write_callback)(char *buffer, | ||||||
|                                       size_t size, |                                       size_t size, | ||||||
| @@ -95,6 +103,23 @@ typedef int (*curl_passwd_callback)(void *clientp, | |||||||
|                                     char *buffer, |                                     char *buffer, | ||||||
|                                     int buflen); |                                     int buflen); | ||||||
|  |  | ||||||
|  | /* the kind of data that is passed to information_callback*/ | ||||||
|  | typedef enum { | ||||||
|  |   CURLINFO_TEXT = 0, | ||||||
|  |   CURLINFO_HEADER_IN,    /* 1 */ | ||||||
|  |   CURLINFO_HEADER_OUT,   /* 2 */ | ||||||
|  |   CURLINFO_DATA_IN,      /* 3 */ | ||||||
|  |   CURLINFO_DATA_OUT,     /* 4 */ | ||||||
|  |   CURLINFO_END | ||||||
|  | } curl_infotype; | ||||||
|  |  | ||||||
|  | typedef int (*curl_debug_callback) | ||||||
|  |        (CURL *handle,      /* the handle/transfer this concerns */ | ||||||
|  |         curl_infotype type, /* what kind of data */ | ||||||
|  |         char *data,        /* points to the data */ | ||||||
|  |         size_t size,       /* size of the data pointed to */ | ||||||
|  |         void *userp);      /* whatever the user please */ | ||||||
|  |    | ||||||
| /* All possible error codes from all sorts of curl functions. Future versions | /* All possible error codes from all sorts of curl functions. Future versions | ||||||
|    may return other values, stay prepared. |    may return other values, stay prepared. | ||||||
|  |  | ||||||
| @@ -158,6 +183,8 @@ typedef enum { | |||||||
|   CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */ |   CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */ | ||||||
|   CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */ |   CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */ | ||||||
|   CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as default */ |   CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as default */ | ||||||
|  |   CURLE_SEND_ERROR,              /* 55 - failed sending network data */ | ||||||
|  |   CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */ | ||||||
|  |  | ||||||
|   CURL_LAST /* never use! */ |   CURL_LAST /* never use! */ | ||||||
| } CURLcode; | } CURLcode; | ||||||
| @@ -172,19 +199,27 @@ typedef enum { | |||||||
|  |  | ||||||
| #define CURL_ERROR_SIZE 256 | #define CURL_ERROR_SIZE 256 | ||||||
|  |  | ||||||
|  | /* long may be 32 or 64 bits, but we should never depend on anything else | ||||||
|  |    but 32 */ | ||||||
|  | #define CURLOPTTYPE_LONG          0 | ||||||
|  | #define CURLOPTTYPE_OBJECTPOINT   10000 | ||||||
|  | #define CURLOPTTYPE_FUNCTIONPOINT 20000 | ||||||
|  |  | ||||||
| /* name is uppercase CURLOPT_<name>, | /* name is uppercase CURLOPT_<name>, | ||||||
|    type is one of the defined CURLOPTTYPE_<type> |    type is one of the defined CURLOPTTYPE_<type> | ||||||
|    number is unique identifier */ |    number is unique identifier */ | ||||||
| #ifdef CINIT | #ifdef CINIT | ||||||
| #undef CINIT | #undef CINIT | ||||||
| #endif | #endif | ||||||
|  | #if defined(__STDC__) || defined(_MSC_VER) | ||||||
| #define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number | #define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number | ||||||
|  | #else | ||||||
| /* long may be 32 or 64 bits, but we should never depend on anything else | /* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ | ||||||
|    but 32 */ | #define LONG          CURLOPTTYPE_LONG | ||||||
| #define CURLOPTTYPE_LONG          0 | #define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT | ||||||
| #define CURLOPTTYPE_OBJECTPOINT   10000 | #define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT | ||||||
| #define CURLOPTTYPE_FUNCTIONPOINT 20000 | #define CINIT(name,type,number) CURLOPT_/**/name = type + number | ||||||
|  | #endif | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|   CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/ |   CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/ | ||||||
| @@ -494,9 +529,26 @@ typedef enum { | |||||||
|   /* DNS cache timeout */ |   /* DNS cache timeout */ | ||||||
|   CINIT(DNS_CACHE_TIMEOUT, LONG, 92), |   CINIT(DNS_CACHE_TIMEOUT, LONG, 92), | ||||||
|  |  | ||||||
|  |   /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/ | ||||||
|  |   CINIT(PREQUOTE, OBJECTPOINT, 93), | ||||||
|  |  | ||||||
|  |   /* set the debug function */ | ||||||
|  |   CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), | ||||||
|  |  | ||||||
|  |   /* set the data for the debug function */ | ||||||
|  |   CINIT(DEBUGDATA, OBJECTPOINT, 95), | ||||||
|  |  | ||||||
|  |   /* mark this as start of a cookie session */ | ||||||
|  |   CINIT(COOKIESESSION, LONG, 96), | ||||||
|  |    | ||||||
|   CURLOPT_LASTENTRY /* the last unusued */ |   CURLOPT_LASTENTRY /* the last unusued */ | ||||||
| } CURLoption; | } CURLoption; | ||||||
|  |  | ||||||
|  |   /* two convenient "aliases" that follow the name scheme better */ | ||||||
|  | #define CURLOPT_WRITEDATA CURLOPT_FILE | ||||||
|  | #define CURLOPT_READDATA  CURLOPT_INFILE  | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ |   /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ | ||||||
| enum { | enum { | ||||||
|   CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd |   CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd | ||||||
| @@ -519,15 +571,26 @@ enum { | |||||||
|  |  | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|   TIMECOND_NONE, |   CURL_TIMECOND_NONE, | ||||||
|  |  | ||||||
|   TIMECOND_IFMODSINCE, |   CURL_TIMECOND_IFMODSINCE, | ||||||
|   TIMECOND_IFUNMODSINCE, |   CURL_TIMECOND_IFUNMODSINCE, | ||||||
|   TIMECOND_LASTMOD, |   CURL_TIMECOND_LASTMOD, | ||||||
|  |  | ||||||
|   TIMECOND_LAST |   CURL_TIMECOND_LAST | ||||||
| } curl_TimeCond; | } curl_TimeCond; | ||||||
|  |  | ||||||
|  | /* for backwards compatibility */ | ||||||
|  | #ifndef TIMECOND_IFMODSINCE | ||||||
|  | #define TIMECOND_IFMODSINCE CURL_TIMECOND_IFMODSINCE | ||||||
|  | #endif | ||||||
|  | #ifndef TIMECOND_IFUNMODSINCE | ||||||
|  | #define TIMECOND_IFUNMODSINCE CURL_TIMECOND_IFUNMODSINCE | ||||||
|  | #endif | ||||||
|  | #ifndef TIMECOND_LASTMOD | ||||||
|  | #define TIMECOND_LASTMOD CURL_TIMECOND_LASTMOD | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef __BEOS__ | #ifdef __BEOS__ | ||||||
| #include <support/SupportDefs.h> | #include <support/SupportDefs.h> | ||||||
| #endif | #endif | ||||||
| @@ -545,16 +608,21 @@ extern int (curl_strnequal)(const char *s1, const char *s2, size_t n); | |||||||
| #define strequal(a,b) curl_strequal(a,b) | #define strequal(a,b) curl_strequal(a,b) | ||||||
| #define strnequal(a,b,c) curl_strnequal(a,b,c) | #define strnequal(a,b,c) curl_strnequal(a,b,c) | ||||||
|  |  | ||||||
| /* external form function */ | /* DEPRECATED function to build formdata */ | ||||||
| int curl_formparse(char *string, | int curl_formparse(char *, struct curl_httppost **, | ||||||
|                    struct HttpPost **httppost, |                    struct curl_httppost **_post); | ||||||
|                    struct HttpPost **last_post); |  | ||||||
|  |  | ||||||
| /* name is uppercase CURLFORM_<name> */ | /* name is uppercase CURLFORM_<name> */ | ||||||
| #ifdef CFINIT | #ifdef CFINIT | ||||||
| #undef CFINIT | #undef CFINIT | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if defined(__STDC__) || defined(_MSC_VER) | ||||||
| #define CFINIT(name) CURLFORM_ ## name | #define CFINIT(name) CURLFORM_ ## name | ||||||
|  | #else | ||||||
|  | /* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ | ||||||
|  | #define CFINIT(name) CURLFORM_/**/name | ||||||
|  | #endif | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|   CFINIT(NOTHING),        /********* the first one is unused ************/ |   CFINIT(NOTHING),        /********* the first one is unused ************/ | ||||||
| @@ -568,29 +636,32 @@ typedef enum { | |||||||
|   CFINIT(CONTENTSLENGTH), |   CFINIT(CONTENTSLENGTH), | ||||||
|   CFINIT(FILECONTENT), |   CFINIT(FILECONTENT), | ||||||
|   CFINIT(ARRAY), |   CFINIT(ARRAY), | ||||||
|   CFINIT(ARRAY_START), /* below are the options allowed within a array */ |   CFINIT(OBSOLETE), | ||||||
|   CFINIT(FILE), |   CFINIT(FILE), | ||||||
|   CFINIT(CONTENTTYPE), |   CFINIT(CONTENTTYPE), | ||||||
|   CFINIT(CONTENTHEADER), |   CFINIT(CONTENTHEADER), | ||||||
|  |   CFINIT(FILENAME), | ||||||
|   CFINIT(END), |   CFINIT(END), | ||||||
|   CFINIT(ARRAY_END),   /* up are the options allowed within a array */ |   CFINIT(OBSOLETE2), | ||||||
|  |  | ||||||
|   CURLFORM_LASTENTRY /* the last unusued */ |   CURLFORM_LASTENTRY /* the last unusued */ | ||||||
| } CURLformoption; | } CURLformoption; | ||||||
|  |  | ||||||
|  | #undef CFINIT /* done */ | ||||||
|  |  | ||||||
| /* structure to be used as parameter for CURLFORM_ARRAY */ | /* structure to be used as parameter for CURLFORM_ARRAY */ | ||||||
| struct curl_forms { | struct curl_forms { | ||||||
| 	CURLformoption		option; | 	CURLformoption		option; | ||||||
| 	const char		*value; | 	const char		*value; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* new external form function */ | /* use this for multipart formpost building */ | ||||||
| int curl_formadd(struct HttpPost **httppost, | int curl_formadd(struct curl_httppost **httppost, | ||||||
|                  struct HttpPost **last_post, |                  struct curl_httppost **last_post, | ||||||
|                  ...); |                  ...); | ||||||
|  |  | ||||||
| /* cleanup a form: */ | /* cleanup a form: */ | ||||||
| void curl_formfree(struct HttpPost *form); | void curl_formfree(struct curl_httppost *form); | ||||||
|  |  | ||||||
| /* Unix and Win32 getenv function call, this returns a malloc()'ed string that | /* Unix and Win32 getenv function call, this returns a malloc()'ed string that | ||||||
|    MUST be free()ed after usage is complete. */ |    MUST be free()ed after usage is complete. */ | ||||||
| @@ -613,8 +684,8 @@ CURLcode curl_global_init(long flags); | |||||||
| void curl_global_cleanup(void); | void curl_global_cleanup(void); | ||||||
|  |  | ||||||
| /* This is the version number */ | /* This is the version number */ | ||||||
| #define LIBCURL_VERSION "7.9.4" | #define LIBCURL_VERSION "7.9.7-pre2" | ||||||
| #define LIBCURL_VERSION_NUM 0x070904 | #define LIBCURL_VERSION_NUM 0x070907 | ||||||
|  |  | ||||||
| /* linked-list structure for the CURLOPT_QUOTE option (and other) */ | /* linked-list structure for the CURLOPT_QUOTE option (and other) */ | ||||||
| struct curl_slist { | struct curl_slist { | ||||||
| @@ -668,14 +739,18 @@ typedef enum { | |||||||
|  |  | ||||||
|   CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, |   CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, | ||||||
|  |  | ||||||
|  |   CURLINFO_REDIRECT_TIME   = CURLINFO_DOUBLE + 19, | ||||||
|  |   CURLINFO_REDIRECT_COUNT  = CURLINFO_LONG + 20, | ||||||
|  |  | ||||||
|   /* Fill in new entries here! */ |   /* Fill in new entries here! */ | ||||||
|  |  | ||||||
|   CURLINFO_LASTONE          = 19 |   CURLINFO_LASTONE          = 21 | ||||||
| } CURLINFO; | } CURLINFO; | ||||||
|  |  | ||||||
| /* unfortunately, the easy.h include file needs the options and info stuff | /* unfortunately, the easy.h and multi.h include files need options and info | ||||||
|    before it can be included! */ |   stuff before they can be included! */ | ||||||
| #include <curl/easy.h> /* nothing in curl is fun without the easy stuff */ | #include <curl/easy.h> /* nothing in curl is fun without the easy stuff */ | ||||||
|  | #include <curl/multi.h> | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|   CURLCLOSEPOLICY_NONE, /* first, never use this */ |   CURLCLOSEPOLICY_NONE, /* first, never use this */ | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -50,7 +50,7 @@ | |||||||
| #ifdef HAVE_SYS_SOCKET_H | #ifdef HAVE_SYS_SOCKET_H | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| #endif | #endif | ||||||
| #ifdef HAVE_WINSOCK_H | #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) | ||||||
| #include <winsock.h> | #include <winsock.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -2,17 +2,19 @@ | |||||||
| # $Id$ | # $Id$ | ||||||
| # | # | ||||||
|  |  | ||||||
| AUTOMAKE_OPTIONS = foreign no-dependencies | AUTOMAKE_OPTIONS = foreign nostdinc | ||||||
|  |  | ||||||
| EXTRA_DIST = getdate.y \ | EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32	    \ | ||||||
|        Makefile.b32 Makefile.b32.resp Makefile.m32 Makefile.vc6 \ |        Makefile.vc6 Makefile.riscos libcurl.def dllinit.c curllib.dsp	    \ | ||||||
|        libcurl.def dllinit.c curllib.dsp curllib.dsw \ |        curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \ | ||||||
|        config-vms.h config-win32.h config-riscos.h config-mac.h |        config.h.in | ||||||
|  |  | ||||||
| lib_LTLIBRARIES = libcurl.la | lib_LTLIBRARIES = libcurl.la | ||||||
|  |  | ||||||
| INCLUDES = -I$(top_srcdir)/include | # we use srcdir/include for the static global include files | ||||||
|  | # we use builddir/lib for the generated lib/config.h file to get found | ||||||
|  | # we use srcdir/lib for the lib-private header files | ||||||
|  | INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/lib -I$(top_srcdir)/lib | ||||||
|  |  | ||||||
| libcurl_la_LDFLAGS = -no-undefined -version-info 2:2:0 | libcurl_la_LDFLAGS = -no-undefined -version-info 2:2:0 | ||||||
| # This flag accepts an argument of the form current[:revision[:age]]. So, | # This flag accepts an argument of the form current[:revision[:age]]. So, | ||||||
| @@ -58,7 +60,7 @@ escape.h       getpass.c      netrc.c        telnet.h       \ | |||||||
| getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \ | getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \ | ||||||
| security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \ | security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \ | ||||||
| http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h \ | http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h \ | ||||||
| llist.c llist.h hash.c hash.h multi.c multi.h | llist.c llist.h hash.c hash.h multi.c | ||||||
|  |  | ||||||
|  |  | ||||||
| noinst_HEADERS = setup.h transfer.h | noinst_HEADERS = setup.h transfer.h | ||||||
|   | |||||||
							
								
								
									
										128
									
								
								lib/Makefile.riscos
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								lib/Makefile.riscos
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | |||||||
|  | # Makefile for project libcurl | ||||||
|  | # Generated on Sun,13 Jan 2002.16:57:00 by EasyGCC (0.1.3 [beta 2] (3 Jan 2002)) | ||||||
|  | # Contact: easygcc@melotech.co.uk | ||||||
|  |  | ||||||
|  | # Project objects: | ||||||
|  | objs =	o.base64 o.connect o.cookie o.dict \ | ||||||
|  | 	o.dllinit o.easy o.escape o.file \ | ||||||
|  | 	o.formdata o.ftp o.getdate o.getenv \ | ||||||
|  | 	o.getinfo o.getpass o.hostip o.http \ | ||||||
|  | 	o.http_chunks o.if2ip o.krb4 o.ldap \ | ||||||
|  | 	o.memdebug o.mprintf o.netrc o.progress \ | ||||||
|  | 	o.security o.sendf o.speedcheck o.ssluse \ | ||||||
|  | 	o.strequal o.strtok o.telnet o.timeval \ | ||||||
|  | 	o.transfer o.url o.version  | ||||||
|  |  | ||||||
|  | # Compile options: | ||||||
|  | linkopts	= -o libcurl | ||||||
|  | compileropts	= -mpoke-function-name -IUtilLib: -mthrowback  | ||||||
|  |  | ||||||
|  | # Project target: | ||||||
|  | libcurl:		$(objs) | ||||||
|  | 		makealf $(linkopts) $(objs) | ||||||
|  |  | ||||||
|  | # Static dependancies: | ||||||
|  | o.base64:	c.base64 | ||||||
|  | 		gcc $(compileropts) -c -o base64.o c.base64 | ||||||
|  |  | ||||||
|  | o.connect:	c.connect | ||||||
|  | 		gcc $(compileropts) -c -o connect.o c.connect | ||||||
|  |  | ||||||
|  | o.cookie:	c.cookie | ||||||
|  | 		gcc $(compileropts) -c -o cookie.o c.cookie | ||||||
|  |  | ||||||
|  | o.dict:	c.dict | ||||||
|  | 		gcc $(compileropts) -c -o dict.o c.dict | ||||||
|  |  | ||||||
|  | o.dllinit:	c.dllinit | ||||||
|  | 		gcc $(compileropts) -c -o dllinit.o c.dllinit | ||||||
|  |  | ||||||
|  | o.easy:	c.easy | ||||||
|  | 		gcc $(compileropts) -c -o easy.o c.easy | ||||||
|  |  | ||||||
|  | o.escape:	c.escape | ||||||
|  | 		gcc $(compileropts) -c -o escape.o c.escape | ||||||
|  |  | ||||||
|  | o.file:	c.file | ||||||
|  | 		gcc $(compileropts) -c -o file.o c.file | ||||||
|  |  | ||||||
|  | o.formdata:	c.formdata | ||||||
|  | 		gcc $(compileropts) -c -o formdata.o c.formdata | ||||||
|  |  | ||||||
|  | o.ftp:	c.ftp | ||||||
|  | 		gcc $(compileropts) -c -o ftp.o c.ftp | ||||||
|  |  | ||||||
|  | o.getdate:	c.getdate | ||||||
|  | 		gcc $(compileropts) -c -o getdate.o c.getdate | ||||||
|  |  | ||||||
|  | o.getenv:	c.getenv | ||||||
|  | 		gcc $(compileropts) -c -o getenv.o c.getenv | ||||||
|  |  | ||||||
|  | o.getinfo:	c.getinfo | ||||||
|  | 		gcc $(compileropts) -c -o getinfo.o c.getinfo | ||||||
|  |  | ||||||
|  | o.getpass:	c.getpass | ||||||
|  | 		gcc $(compileropts) -c -o getpass.o c.getpass | ||||||
|  |  | ||||||
|  | o.hostip:	c.hostip | ||||||
|  | 		gcc $(compileropts) -c -o hostip.o c.hostip | ||||||
|  |  | ||||||
|  | o.http:	c.http | ||||||
|  | 		gcc $(compileropts) -c -o http.o c.http | ||||||
|  |  | ||||||
|  | o.http_chunks:	c.http_chunks | ||||||
|  | 		gcc $(compileropts) -c -o http_chunks.o c.http_chunks | ||||||
|  |  | ||||||
|  | o.if2ip:	c.if2ip | ||||||
|  | 		gcc $(compileropts) -c -o if2ip.o c.if2ip | ||||||
|  |  | ||||||
|  | o.krb4:	c.krb4 | ||||||
|  | 		gcc $(compileropts) -c -o krb4.o c.krb4 | ||||||
|  |  | ||||||
|  | o.ldap:	c.ldap | ||||||
|  | 		gcc $(compileropts) -IOpenLDAP: -c -o ldap.o c.ldap | ||||||
|  |  | ||||||
|  | o.memdebug:	c.memdebug | ||||||
|  | 		gcc $(compileropts) -c -o memdebug.o c.memdebug | ||||||
|  |  | ||||||
|  | o.mprintf:	c.mprintf | ||||||
|  | 		gcc $(compileropts) -c -o mprintf.o c.mprintf | ||||||
|  |  | ||||||
|  | o.netrc:	c.netrc | ||||||
|  | 		gcc $(compileropts) -c -o netrc.o c.netrc | ||||||
|  |  | ||||||
|  | o.progress:	c.progress | ||||||
|  | 		gcc $(compileropts) -c -o progress.o c.progress | ||||||
|  |  | ||||||
|  | o.security:	c.security | ||||||
|  | 		gcc $(compileropts) -c -o security.o c.security | ||||||
|  |  | ||||||
|  | o.sendf:	c.sendf | ||||||
|  | 		gcc $(compileropts) -c -o sendf.o c.sendf | ||||||
|  |  | ||||||
|  | o.speedcheck:	c.speedcheck | ||||||
|  | 		gcc $(compileropts) -c -o speedcheck.o c.speedcheck | ||||||
|  |  | ||||||
|  | o.ssluse:	c.ssluse | ||||||
|  | 		gcc $(compileropts) -c -o ssluse.o c.ssluse | ||||||
|  |  | ||||||
|  | o.strequal:	c.strequal | ||||||
|  | 		gcc $(compileropts) -c -o strequal.o c.strequal | ||||||
|  |  | ||||||
|  | o.strtok:	c.strtok | ||||||
|  | 		gcc $(compileropts) -c -o strtok.o c.strtok | ||||||
|  |  | ||||||
|  | o.telnet:	c.telnet | ||||||
|  | 		gcc $(compileropts) -c -o telnet.o c.telnet | ||||||
|  |  | ||||||
|  | o.timeval:	c.timeval | ||||||
|  | 		gcc $(compileropts) -c -o timeval.o c.timeval | ||||||
|  |  | ||||||
|  | o.transfer:	c.transfer | ||||||
|  | 		gcc $(compileropts) -c -o transfer.o c.transfer | ||||||
|  |  | ||||||
|  | o.url:	c.url | ||||||
|  | 		gcc $(compileropts) -c -o url.o c.url | ||||||
|  |  | ||||||
|  | o.version:	c.version | ||||||
|  | 		gcc $(compileropts) -c -o version.o c.version | ||||||
| @@ -47,12 +47,9 @@ CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB | |||||||
| LNKDLL    = link.exe /DLL  /def:libcurl.def | LNKDLL    = link.exe /DLL  /def:libcurl.def | ||||||
| LNKLIB    = link.exe -lib | LNKLIB    = link.exe -lib | ||||||
| LFLAGS    = /nologo | LFLAGS    = /nologo | ||||||
| LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)/out32dll |  | ||||||
| LINKLIBS  = ws2_32.lib | LINKLIBS  = ws2_32.lib | ||||||
| SSLLIBS   = libeay32.lib ssleay32.lib RSAglue.lib | SSLLIBS   = libeay32.lib ssleay32.lib RSAglue.lib | ||||||
| CFGSET    = FALSE | CFGSET    = FALSE | ||||||
| LFLAGSSSL= |  | ||||||
| SSLLIBS  = |  | ||||||
|  |  | ||||||
| ###################### | ###################### | ||||||
| # release | # release | ||||||
| @@ -82,8 +79,9 @@ CFGSET = TRUE | |||||||
| !IF "$(CFG)" == "release-ssl" | !IF "$(CFG)" == "release-ssl" | ||||||
| TARGET   =$(LIB_NAME).lib | TARGET   =$(LIB_NAME).lib | ||||||
| DIROBJ   =.\$(CFG) | DIROBJ   =.\$(CFG) | ||||||
|  | LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32" | ||||||
| LNK      = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET) | LNK      = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET) | ||||||
| LINKLIBS = $(LINKLIBS) $(SSLLIBS) | LINKLIBS = $(LINKLIBS) | ||||||
| CC       = $(CCNODBG) $(CFLAGSSSL) | CC       = $(CCNODBG) $(CFLAGSSSL) | ||||||
| CFGSET   = TRUE | CFGSET   = TRUE | ||||||
| !ENDIF | !ENDIF | ||||||
| @@ -94,15 +92,13 @@ CFGSET   = TRUE | |||||||
| !IF "$(CFG)" == "release-ssl-dll" | !IF "$(CFG)" == "release-ssl-dll" | ||||||
| TARGET   =$(LIB_NAME).dll | TARGET   =$(LIB_NAME).dll | ||||||
| DIROBJ   =.\$(CFG) | DIROBJ   =.\$(CFG) | ||||||
|  | LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll" | ||||||
| LNK      = $(LNKDLL) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib" | LNK      = $(LNKDLL) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib" | ||||||
| LINKLIBS = $(LINKLIBS) $(SSLLIBS) | LINKLIBS = $(LINKLIBS) $(SSLLIBS) | ||||||
| CC       = $(CCNODBG)  $(CFLAGSSSL) | CC       = $(CCNODBG)  $(CFLAGSSSL) | ||||||
| CFGSET   = TRUE | CFGSET   = TRUE | ||||||
| !ENDIF | !ENDIF | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ###################### | ###################### | ||||||
| # debug | # debug | ||||||
|  |  | ||||||
| @@ -132,7 +128,7 @@ CFGSET = TRUE | |||||||
| TARGET   = $(LIB_NAME_DEBUG).lib | TARGET   = $(LIB_NAME_DEBUG).lib | ||||||
| DIROBJ   =.\$(CFG) | DIROBJ   =.\$(CFG) | ||||||
| LNK      = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET) | LNK      = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET) | ||||||
| LINKLIBS = $(LINKLIBS) $(SSLLIBS) | LINKLIBS = $(LINKLIBS) | ||||||
| CC       = $(CCDEBUG) $(CFLAGSSSL) | CC       = $(CCDEBUG) $(CFLAGSSSL) | ||||||
| CFGSET   = TRUE | CFGSET   = TRUE | ||||||
| !ENDIF | !ENDIF | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Andrew Francis and Daniel Stenberg |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -1,25 +1,390 @@ | |||||||
|  | /* config.h.in.  Generated automatically from configure.in by autoheader.  */ | ||||||
|  | /* Name of this package! */ | ||||||
|  | #undef PACKAGE | ||||||
|  |  | ||||||
| #define socklen_t int | /* Version number of this archive. */ | ||||||
|  | #undef VERSION | ||||||
|  |  | ||||||
| #define HAVE_SYS_SOCKET_H | /* Define if you have the getpass function.  */ | ||||||
|  | #undef HAVE_GETPASS | ||||||
|  |  | ||||||
|  | /* Define cpu-machine-OS */ | ||||||
|  | #define OS "ARM-RISC 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 | ||||||
|  |  | ||||||
|  | /* 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 | ||||||
|  |  | ||||||
|  | /* Define this to 'int' if socklen_t is not an available typedefed type */ | ||||||
|  | #undef socklen_t | ||||||
|  |  | ||||||
|  | /* Define this as a suitable file to read random data from */ | ||||||
|  | #undef RANDOM_FILE | ||||||
|  |  | ||||||
|  | /* Define this to your Entropy Gathering Daemon socket pathname */ | ||||||
|  | #undef EGD_SOCKET | ||||||
|  |  | ||||||
|  | /* Define if you have a working OpenSSL installation */ | ||||||
|  | #undef OPENSSL_ENABLED | ||||||
|  |  | ||||||
|  | /* Set to explicitly specify we don't want to use thread-safe functions */ | ||||||
|  | #define DISABLED_THREADSAFE | ||||||
|  |  | ||||||
|  | /* Define if you want to enable IPv6 support */ | ||||||
|  | #undef ENABLE_IPV6 | ||||||
|  |  | ||||||
|  | /* Define if you have the <alloca.h> header file. */ | ||||||
|  | #define HAVE_ALLOCA_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <arpa/inet.h> header file. */ | ||||||
| #define HAVE_ARPA_INET_H | #define HAVE_ARPA_INET_H | ||||||
| #define HAVE_SYS_SELECT_H |  | ||||||
|  | /* Define if you have the `closesocket' function. */ | ||||||
|  | #undef HAVE_CLOSESOCKET | ||||||
|  |  | ||||||
|  | /* 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 `dlopen' function. */ | ||||||
|  | #undef HAVE_DLOPEN | ||||||
|  |  | ||||||
|  | /* Define if you have the <err.h> header file. */ | ||||||
|  | #undef HAVE_ERR_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <fcntl.h> header file. */ | ||||||
| #define HAVE_FCNTL_H | #define HAVE_FCNTL_H | ||||||
|  |  | ||||||
|  | /* Define if getaddrinfo exists and works */ | ||||||
|  | #define HAVE_GETADDRINFO | ||||||
|  |  | ||||||
|  | /* Define if you have the `geteuid' function. */ | ||||||
|  | #undef HAVE_GETEUID | ||||||
|  |  | ||||||
|  | /* Define if you have the `gethostbyaddr' function. */ | ||||||
|  | #define 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. */ | ||||||
|  | #define HAVE_GETHOSTNAME | ||||||
|  |  | ||||||
|  | /* Define if you have the <getopt.h> header file. */ | ||||||
|  | #define HAVE_GETOPT_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `getpass_r' function. */ | ||||||
|  | #undef HAVE_GETPASS_R | ||||||
|  |  | ||||||
|  | /* Define if you have the `getpwuid' function. */ | ||||||
|  | #undef HAVE_GETPWUID | ||||||
|  |  | ||||||
|  | /* Define if you have the `getservbyname' function. */ | ||||||
|  | #undef HAVE_GETSERVBYNAME | ||||||
|  |  | ||||||
|  | /* Define if you have the `gettimeofday' function. */ | ||||||
| #define HAVE_GETTIMEOFDAY | #define 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 <inttypes.h> header file. */ | ||||||
|  | #define HAVE_INTTYPES_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <io.h> header file. */ | ||||||
|  | #define HAVE_IO_H | ||||||
|  |  | ||||||
|  | /* 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 <krb.h> header file. */ | ||||||
|  | #undef HAVE_KRB_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 | ||||||
|  |  | ||||||
|  | /* Define if you have the `localtime_r' function. */ | ||||||
|  | #undef HAVE_LOCALTIME_R | ||||||
|  |  | ||||||
|  | /* Define if you have the <malloc.h> header file. */ | ||||||
|  | #define HAVE_MALLOC_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <memory.h> header file. */ | ||||||
|  | #undef HAVE_MEMORY_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <netdb.h> header file. */ | ||||||
|  | #define 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. */ | ||||||
|  | #define HAVE_NETINET_IN_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <net/if.h> header file. */ | ||||||
|  | #define HAVE_NET_IF_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 `perror' function. */ | ||||||
|  | #undef HAVE_PERROR | ||||||
|  |  | ||||||
|  | /* Define if you have the <pwd.h> header file. */ | ||||||
|  | #undef HAVE_PWD_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `RAND_egd' function. */ | ||||||
|  | #undef HAVE_RAND_EGD | ||||||
|  |  | ||||||
|  | /* 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 <rsa.h> header file. */ | ||||||
|  | #undef HAVE_RSA_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `select' function. */ | ||||||
| #define HAVE_SELECT | #define HAVE_SELECT | ||||||
|  |  | ||||||
|  | /* Define if you have the `setvbuf' function. */ | ||||||
|  | #undef HAVE_SETVBUF | ||||||
|  |  | ||||||
|  | /* Define if you have the <sgtty.h> header file. */ | ||||||
|  | #define HAVE_SGTTY_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `sigaction' function. */ | ||||||
|  | #undef HAVE_SIGACTION | ||||||
|  |  | ||||||
|  | /* Define if you have the `signal' function. */ | ||||||
|  | #define HAVE_SIGNAL | ||||||
|  |  | ||||||
|  | /* Define if you have the `socket' function. */ | ||||||
| #define HAVE_SOCKET | #define HAVE_SOCKET | ||||||
|  |  | ||||||
|  | /* Define if you have the <ssl.h> header file. */ | ||||||
|  | #undef HAVE_SSL_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <stdint.h> header file. */ | ||||||
|  | #undef HAVE_STDINT_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <stdlib.h> header file. */ | ||||||
|  | #define HAVE_STDLIB_H | ||||||
|  |  | ||||||
|  | /* 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. */ | ||||||
|  | #define HAVE_STRDUP | ||||||
|  |  | ||||||
|  | /* Define if you have the `strftime' function. */ | ||||||
|  | #define HAVE_STRFTIME | ||||||
|  |  | ||||||
|  | /* Define if you have the `stricmp' function. */ | ||||||
|  | #define HAVE_STRICMP | ||||||
|  |  | ||||||
|  | /* Define if you have the <strings.h> header file. */ | ||||||
|  | #undef HAVE_STRINGS_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <string.h> header file. */ | ||||||
|  | #define HAVE_STRING_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `strlcat' function. */ | ||||||
|  | #undef HAVE_STRLCAT | ||||||
|  |  | ||||||
|  | /* Define if you have the `strlcpy' function. */ | ||||||
|  | #undef HAVE_STRLCPY | ||||||
|  |  | ||||||
|  | /* Define if you have the `strstr' function. */ | ||||||
|  | #define HAVE_STRSTR | ||||||
|  |  | ||||||
|  | /* Define if you have the `strtok_r' function. */ | ||||||
|  | #undef HAVE_STRTOK_R | ||||||
|  |  | ||||||
|  | /* 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. */ | ||||||
|  | #define 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. */ | ||||||
|  | #define HAVE_SYS_TIME_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <sys/types.h> header file. */ | ||||||
|  | #define HAVE_SYS_TYPES_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `tcgetattr' function. */ | ||||||
|  | #define HAVE_TCGETATTR | ||||||
|  |  | ||||||
|  | /* Define if you have the `tcsetattr' function. */ | ||||||
|  | #define HAVE_TCSETATTR | ||||||
|  |  | ||||||
|  | /* Define if you have the <termios.h> header file. */ | ||||||
|  | #define HAVE_TERMIOS_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <termio.h> header file. */ | ||||||
|  | #undef HAVE_TERMIO_H | ||||||
|  |  | ||||||
|  | /* Define if you have the <time.h> header file. */ | ||||||
|  | #undef HAVE_TIME_H | ||||||
|  |  | ||||||
|  | /* Define if you have the `uname' function. */ | ||||||
|  | #define HAVE_UNAME | ||||||
|  |  | ||||||
|  | /* Define if you have the <unistd.h> header file. */ | ||||||
|  | #define 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 | ||||||
|  |  | ||||||
|  | /* Name of package */ | ||||||
|  | #undef PACKAGE | ||||||
|  |  | ||||||
|  | /* Define as the return type of signal handlers (`int' or `void'). */ | ||||||
|  | #define RETSIGTYPE void | ||||||
|  |  | ||||||
|  | /* The size of a `long double', as computed by sizeof. */ | ||||||
|  | #undef SIZEOF_LONG_DOUBLE | ||||||
|  |  | ||||||
|  | /* The size of a `long long', as computed by sizeof. */ | ||||||
|  | #undef SIZEOF_LONG_LONG | ||||||
|  |  | ||||||
|  | /* 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 | ||||||
|  |  | ||||||
|  | /* Version number of package */ | ||||||
|  | #undef VERSION | ||||||
|  |  | ||||||
|  | /* 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 | ||||||
|  |  | ||||||
|  | /* Number of bits in a file offset, on hosts where this is settable. */ | ||||||
|  | #undef _FILE_OFFSET_BITS | ||||||
|  |  | ||||||
|  | /* Define for large files, on AIX-style hosts. */ | ||||||
|  | #undef _LARGE_FILES | ||||||
|  |  | ||||||
|  | /* Define to empty if `const' does not conform to ANSI C. */ | ||||||
|  | #undef const | ||||||
|  |  | ||||||
|  | /* Define to `unsigned' if <sys/types.h> does not define. */ | ||||||
|  | #undef size_t | ||||||
|  |  | ||||||
|  | /* type to use in place of socklen_t if not defined */ | ||||||
|  | #undef socklen_t | ||||||
|  |  | ||||||
|  | /* Define to `int' if <sys/types.h> does not define. */ | ||||||
|  | #undef ssize_t | ||||||
|  |  | ||||||
|  | /* this is a quick hack.  I hope it's correct. */ | ||||||
| #define ifr_dstaddr ifr_addr | #define ifr_dstaddr ifr_addr | ||||||
|  |  | ||||||
|  | #define IOCTL_3_ARGS | ||||||
|  |  | ||||||
| #include <sys/socket.h> | #define HAVE_FIONBIO | ||||||
| #include <sys/if.h> |  | ||||||
| #include <sys/fcntl.h> |  | ||||||
| #include <sys/ioctl.h> |  | ||||||
| #include <netinet/in.h> |  | ||||||
| #include <netdb.h> |  | ||||||
|  |  | ||||||
| #define ioctl(a,b,c,d) (ioctl(a,b,c) * (d==d)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define OS "RISC OS" |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -185,7 +185,6 @@ int waitconnect(int sockfd, /* socket */ | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifndef ENABLE_IPV6 |  | ||||||
| static CURLcode bindlocal(struct connectdata *conn, | static CURLcode bindlocal(struct connectdata *conn, | ||||||
|                           int sockfd) |                           int sockfd) | ||||||
| { | { | ||||||
| @@ -207,22 +206,28 @@ static CURLcode bindlocal(struct connectdata *conn, | |||||||
|    *************************************************************/ |    *************************************************************/ | ||||||
|   if (strlen(data->set.device)<255) { |   if (strlen(data->set.device)<255) { | ||||||
|     struct sockaddr_in sa; |     struct sockaddr_in sa; | ||||||
|     struct hostent *h=NULL; |     Curl_addrinfo *h=NULL; | ||||||
|     char *hostdataptr=NULL; |  | ||||||
|     size_t size; |     size_t size; | ||||||
|     char myhost[256] = ""; |     char myhost[256] = ""; | ||||||
|     in_addr_t in; |     in_addr_t in; | ||||||
|  |  | ||||||
|     if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { |     if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { | ||||||
|       h = Curl_resolv(data, myhost, 0, &hostdataptr); |       /* | ||||||
|  |        * We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer | ||||||
|  |        */ | ||||||
|  |       h = Curl_resolv(data, myhost, 0); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       if(strlen(data->set.device)>1) { |       if(strlen(data->set.device)>1) { | ||||||
|         h = Curl_resolv(data, data->set.device, 0, &hostdataptr); |         /* | ||||||
|       } |          * This was not an interface, resolve the name as a host name | ||||||
|       if(h) { |          * or IP number | ||||||
|         /* we know data->set.device is shorter than the myhost array */ |          */ | ||||||
|         strcpy(myhost, data->set.device); |         h = Curl_resolv(data, data->set.device, 0); | ||||||
|  |         if(h) { | ||||||
|  |           /* we know data->set.device is shorter than the myhost array */ | ||||||
|  |           strcpy(myhost, data->set.device); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -243,10 +248,13 @@ static CURLcode bindlocal(struct connectdata *conn, | |||||||
|  |  | ||||||
|       if ( h ) { |       if ( h ) { | ||||||
|         memset((char *)&sa, 0, sizeof(sa)); |         memset((char *)&sa, 0, sizeof(sa)); | ||||||
|         memcpy((char *)&sa.sin_addr, | #ifdef ENABLE_IPV6 | ||||||
|                h->h_addr, |         memcpy((char *)&sa.sin_addr, h->ai_addr, h->ai_addrlen);         | ||||||
|                h->h_length); |         sa.sin_family = h->ai_family; | ||||||
|  | #else | ||||||
|  |         memcpy((char *)&sa.sin_addr, h->h_addr, h->h_length); | ||||||
|         sa.sin_family = AF_INET; |         sa.sin_family = AF_INET; | ||||||
|  | #endif | ||||||
|         sa.sin_addr.s_addr = in; |         sa.sin_addr.s_addr = in; | ||||||
|         sa.sin_port = 0; /* get any port */ |         sa.sin_port = 0; /* get any port */ | ||||||
| 	 | 	 | ||||||
| @@ -314,7 +322,7 @@ static CURLcode bindlocal(struct connectdata *conn, | |||||||
|  |  | ||||||
|   return CURLE_HTTP_PORT_FAILED; |   return CURLE_HTTP_PORT_FAILED; | ||||||
| } | } | ||||||
| #endif /* end of ipv4-specific section */ |  | ||||||
|  |  | ||||||
| static | static | ||||||
| int socketerror(int sockfd) | int socketerror(int sockfd) | ||||||
| @@ -345,6 +353,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|   int rc; |   int rc; | ||||||
|   int sockfd=-1; |   int sockfd=-1; | ||||||
|   int aliasindex=0; |   int aliasindex=0; | ||||||
|  |   char *hostname; | ||||||
|  |  | ||||||
|   struct timeval after; |   struct timeval after; | ||||||
|   struct timeval before = Curl_tvnow(); |   struct timeval before = Curl_tvnow(); | ||||||
| @@ -364,8 +373,13 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     /* get the most strict timeout of the ones converted to milliseconds */ |     /* get the most strict timeout of the ones converted to milliseconds */ | ||||||
|     if(data->set.timeout && |     if(data->set.timeout && data->set.connecttimeout) { | ||||||
|        (data->set.timeout < data->set.connecttimeout)) |       if (data->set.timeout < data->set.connecttimeout) | ||||||
|  |         timeout_ms = data->set.timeout*1000; | ||||||
|  |       else  | ||||||
|  |         timeout_ms = data->set.connecttimeout*1000; | ||||||
|  |     } | ||||||
|  |     else if(data->set.timeout) | ||||||
|       timeout_ms = data->set.timeout*1000; |       timeout_ms = data->set.timeout*1000; | ||||||
|     else |     else | ||||||
|       timeout_ms = data->set.connecttimeout*1000; |       timeout_ms = data->set.connecttimeout*1000; | ||||||
| @@ -380,6 +394,9 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   hostname = data->change.proxy?conn->proxyhost:conn->hostname; | ||||||
|  |   infof(data, "About to connect() to %s:%d\n", hostname, port); | ||||||
|  |  | ||||||
| #ifdef ENABLE_IPV6 | #ifdef ENABLE_IPV6 | ||||||
|   /* |   /* | ||||||
|    * Connecting with IPv6 support is so much easier and cleanly done |    * Connecting with IPv6 support is so much easier and cleanly done | ||||||
| @@ -393,6 +410,14 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|       if (sockfd < 0) |       if (sockfd < 0) | ||||||
|         continue; |         continue; | ||||||
|  |  | ||||||
|  |       if(conn->data->set.device) { | ||||||
|  |         /* user selected to bind the outgoing socket to a specified "device" | ||||||
|  |            before doing connect */ | ||||||
|  |         CURLcode res = bindlocal(conn, sockfd); | ||||||
|  |         if(res) | ||||||
|  |           return res; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       /* set socket non-blocking */ |       /* set socket non-blocking */ | ||||||
|       Curl_nonblock(sockfd, TRUE); |       Curl_nonblock(sockfd, TRUE); | ||||||
|  |  | ||||||
| @@ -419,7 +444,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|         case ECONNREFUSED: /* no one listening */ |         case ECONNREFUSED: /* no one listening */ | ||||||
|         default: |         default: | ||||||
|           /* unknown error, fallthrough and try another address! */ |           /* unknown error, fallthrough and try another address! */ | ||||||
|           failf(data, "Failed to connect"); |           failf(data, "Failed connect to %s: %d", hostname, error); | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -449,10 +474,8 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|       before = after; |       before = after; | ||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
|     if (sockfd < 0) { |     if (sockfd < 0) | ||||||
|       failf(data, "connect() failed"); |  | ||||||
|       return CURLE_COULDNT_CONNECT; |       return CURLE_COULDNT_CONNECT; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* leave the socket in non-blocking mode */ |     /* leave the socket in non-blocking mode */ | ||||||
|  |  | ||||||
| @@ -524,7 +547,8 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|         break; |         break; | ||||||
|       default: |       default: | ||||||
|         /* unknown error, fallthrough and try another address! */ |         /* unknown error, fallthrough and try another address! */ | ||||||
|         failf(data, "Failed to connect to IP number %d", aliasindex+1); |         failf(data, "Failed to connect to %s IP number %d: %d", | ||||||
|  |               hostname, aliasindex+1, error); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -556,7 +580,6 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */ | |||||||
|     /* no good connect was made */ |     /* no good connect was made */ | ||||||
|     sclose(sockfd); |     sclose(sockfd); | ||||||
|     *sockconn = -1; |     *sockconn = -1; | ||||||
|     failf(data, "Couldn't connect to host"); |  | ||||||
|     return CURLE_COULDNT_CONNECT; |     return CURLE_COULDNT_CONNECT; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
							
								
								
									
										122
									
								
								lib/cookie.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								lib/cookie.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -93,6 +93,21 @@ Example set of cookies: | |||||||
| #include "memdebug.h" | #include "memdebug.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | free_cookiemess(struct Cookie *co) | ||||||
|  | { | ||||||
|  |   if(co->domain) | ||||||
|  |     free(co->domain); | ||||||
|  |   if(co->path) | ||||||
|  |     free(co->path); | ||||||
|  |   if(co->name) | ||||||
|  |     free(co->name); | ||||||
|  |   if(co->value) | ||||||
|  |     free(co->value); | ||||||
|  |  | ||||||
|  |   free(co); | ||||||
|  | } | ||||||
|  |  | ||||||
| /**************************************************************************** | /**************************************************************************** | ||||||
|  * |  * | ||||||
|  * Curl_cookie_add() |  * Curl_cookie_add() | ||||||
| @@ -127,25 +142,48 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
| 	     | 	     | ||||||
|   if(httpheader) { |   if(httpheader) { | ||||||
|     /* This line was read off a HTTP-header */ |     /* This line was read off a HTTP-header */ | ||||||
|  |     char *sep; | ||||||
|     semiptr=strchr(lineptr, ';'); /* first, find a semicolon */ |     semiptr=strchr(lineptr, ';'); /* first, find a semicolon */ | ||||||
|     ptr = lineptr; |     ptr = lineptr; | ||||||
|     do { |     do { | ||||||
|       /* we have a <what>=<this> pair or a 'secure' word here */ |       /* we have a <what>=<this> pair or a 'secure' word here */ | ||||||
|       if(strchr(ptr, '=')) { |       sep = strchr(ptr, '='); | ||||||
|  |       if(sep && (!semiptr || (semiptr>sep)) ) { | ||||||
|  |         /* | ||||||
|  |          * There is a = sign and if there was a semicolon too, which make sure | ||||||
|  |          * that the semicolon comes _after_ the equal sign. | ||||||
|  |          */ | ||||||
|  |  | ||||||
|         name[0]=what[0]=0; /* init the buffers */ |         name[0]=what[0]=0; /* init the buffers */ | ||||||
|         if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^=]=%" |         if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;=]=%" | ||||||
|                        MAX_COOKIE_LINE_TXT "[^;\r\n]", |                        MAX_COOKIE_LINE_TXT "[^;\r\n]", | ||||||
|                        name, what)) { |                        name, what)) { | ||||||
|           /* this is a legal <what>=<this> pair */ |           /* this is a <name>=<what> pair */ | ||||||
|  |  | ||||||
|  |           char *whatptr; | ||||||
|  |  | ||||||
|  |           /* Strip off trailing whitespace from the 'what' */ | ||||||
|  |           int len=strlen(what); | ||||||
|  |           while(len && isspace((int)what[len-1])) { | ||||||
|  |             what[len-1]=0; | ||||||
|  |             len--; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           /* Skip leading whitespace from the 'what' */ | ||||||
|  |           whatptr=what; | ||||||
|  |           while(isspace((int)*whatptr)) { | ||||||
|  |             whatptr++; | ||||||
|  |           } | ||||||
|  |  | ||||||
|           if(strequal("path", name)) { |           if(strequal("path", name)) { | ||||||
|             co->path=strdup(what); |             co->path=strdup(whatptr); | ||||||
|           } |           } | ||||||
|           else if(strequal("domain", name)) { |           else if(strequal("domain", name)) { | ||||||
|             co->domain=strdup(what); |             co->domain=strdup(whatptr); | ||||||
|  |             co->field1= (whatptr[0]=='.')?2:1; | ||||||
|           } |           } | ||||||
|           else if(strequal("version", name)) { |           else if(strequal("version", name)) { | ||||||
|             co->version=strdup(what); |             co->version=strdup(whatptr); | ||||||
|           } |           } | ||||||
|           else if(strequal("max-age", name)) { |           else if(strequal("max-age", name)) { | ||||||
|             /* Defined in RFC2109: |             /* Defined in RFC2109: | ||||||
| @@ -157,17 +195,17 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|                cookie should be discarded immediately. |                cookie should be discarded immediately. | ||||||
|  |  | ||||||
|              */ |              */ | ||||||
|             co->maxage = strdup(what); |             co->maxage = strdup(whatptr); | ||||||
|             co->expires = |             co->expires = | ||||||
|               atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]); |               atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now; | ||||||
|           } |           } | ||||||
|           else if(strequal("expires", name)) { |           else if(strequal("expires", name)) { | ||||||
|             co->expirestr=strdup(what); |             co->expirestr=strdup(whatptr); | ||||||
|             co->expires = curl_getdate(what, &now); |             co->expires = curl_getdate(what, &now); | ||||||
|           } |           } | ||||||
|           else if(!co->name) { |           else if(!co->name) { | ||||||
|             co->name = strdup(name); |             co->name = strdup(name); | ||||||
|             co->value = strdup(what); |             co->value = strdup(whatptr); | ||||||
|           } |           } | ||||||
|           /* |           /* | ||||||
|             else this is the second (or more) name we don't know |             else this is the second (or more) name we don't know | ||||||
| @@ -187,8 +225,11 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|  |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       if(!semiptr) |       if(!semiptr || !*semiptr) { | ||||||
|         continue; /* we already know there are no more cookies */ |         /* we already know there are no more cookies */ | ||||||
|  |         semiptr = NULL; | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       ptr=semiptr+1; |       ptr=semiptr+1; | ||||||
|       while(ptr && *ptr && isspace((int)*ptr)) |       while(ptr && *ptr && isspace((int)*ptr)) | ||||||
| @@ -198,9 +239,23 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|       if(!semiptr && *ptr) |       if(!semiptr && *ptr) | ||||||
|         /* There are no more semicolons, but there's a final name=value pair |         /* There are no more semicolons, but there's a final name=value pair | ||||||
|            coming up */ |            coming up */ | ||||||
|         semiptr=ptr; |         semiptr=strchr(ptr, '\0'); | ||||||
|     } while(semiptr); |     } while(semiptr); | ||||||
|  |  | ||||||
|  |     if(NULL == co->name) { | ||||||
|  |       /* we didn't get a cookie name, this is an illegal line, bail out */ | ||||||
|  |       if(co->domain) | ||||||
|  |         free(co->domain); | ||||||
|  |       if(co->path) | ||||||
|  |         free(co->path); | ||||||
|  |       if(co->name) | ||||||
|  |         free(co->name); | ||||||
|  |       if(co->value) | ||||||
|  |         free(co->value); | ||||||
|  |       free(co); | ||||||
|  |       return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if(NULL == co->domain) |     if(NULL == co->domain) | ||||||
|       /* no domain given in the header line, set the default now */ |       /* no domain given in the header line, set the default now */ | ||||||
|       co->domain=domain?strdup(domain):NULL; |       co->domain=domain?strdup(domain):NULL; | ||||||
| @@ -286,22 +341,19 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|     if(7 != fields) { |     if(7 != fields) { | ||||||
|       /* we did not find the sufficient number of fields to recognize this |       /* we did not find the sufficient number of fields to recognize this | ||||||
|          as a valid line, abort and go home */ |          as a valid line, abort and go home */ | ||||||
|  |       free_cookiemess(co); | ||||||
|       if(co->domain) |  | ||||||
|         free(co->domain); |  | ||||||
|       if(co->path) |  | ||||||
|         free(co->path); |  | ||||||
|       if(co->name) |  | ||||||
|         free(co->name); |  | ||||||
|       if(co->value) |  | ||||||
|         free(co->value); |  | ||||||
|  |  | ||||||
|       free(co); |  | ||||||
|       return NULL; |       return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if(!c->running &&    /* read from a file */ | ||||||
|  |      c->newsession &&  /* clean session cookies */ | ||||||
|  |      !co->expires) {   /* this is a session cookie since it doesn't expire! */ | ||||||
|  |     free_cookiemess(co); | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   co->livecookie = c->running; |   co->livecookie = c->running; | ||||||
|  |  | ||||||
|   /* now, we have parsed the incoming line, we must now check if this |   /* now, we have parsed the incoming line, we must now check if this | ||||||
| @@ -315,7 +367,13 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|       /* the names are identical */ |       /* the names are identical */ | ||||||
|  |  | ||||||
|       if(clist->domain && co->domain) { |       if(clist->domain && co->domain) { | ||||||
|         if(strequal(clist->domain, co->domain)) |         if(strequal(clist->domain, co->domain) || | ||||||
|  |            (clist->domain[0]=='.' && | ||||||
|  |             strequal(&(clist->domain[1]), co->domain)) || | ||||||
|  |            (co->domain[0]=='.' && | ||||||
|  |             strequal(clist->domain, &(co->domain[1]))) ) | ||||||
|  |           /* The domains are identical, or at least identical if you skip the | ||||||
|  |              preceeding dot */ | ||||||
|           replace_old=TRUE; |           replace_old=TRUE; | ||||||
|       } |       } | ||||||
|       else if(!clist->domain && !co->domain) |       else if(!clist->domain && !co->domain) | ||||||
| @@ -416,8 +474,12 @@ Curl_cookie_add(struct CookieInfo *c, | |||||||
|  * Inits a cookie struct to read data from a local file. This is always |  * Inits a cookie struct to read data from a local file. This is always | ||||||
|  * called before any cookies are set. File may be NULL. |  * called before any cookies are set. File may be NULL. | ||||||
|  * |  * | ||||||
|  |  * If 'newsession' is TRUE, discard all "session cookies" on read from file. | ||||||
|  |  * | ||||||
|  ****************************************************************************/ |  ****************************************************************************/ | ||||||
| struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) | struct CookieInfo *Curl_cookie_init(char *file, | ||||||
|  |                                     struct CookieInfo *inc, | ||||||
|  |                                     bool newsession) | ||||||
| { | { | ||||||
|   char line[MAX_COOKIE_LINE]; |   char line[MAX_COOKIE_LINE]; | ||||||
|   struct CookieInfo *c; |   struct CookieInfo *c; | ||||||
| @@ -445,6 +507,8 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) | |||||||
|   else |   else | ||||||
|     fp = file?fopen(file, "r"):NULL; |     fp = file?fopen(file, "r"):NULL; | ||||||
|  |  | ||||||
|  |   c->newsession = newsession; /* new session? */ | ||||||
|  |  | ||||||
|   if(fp) { |   if(fp) { | ||||||
|     char *lineptr; |     char *lineptr; | ||||||
|     bool headerline; |     bool headerline; | ||||||
| @@ -467,7 +531,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) | |||||||
|       fclose(fp); |       fclose(fp); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   c->running = TRUE; /* now, we're running */ |   c->running = TRUE;          /* now, we're running */ | ||||||
|  |  | ||||||
|   return c; |   return c; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -55,9 +55,10 @@ struct CookieInfo { | |||||||
|   /* linked list of cookies we know of */ |   /* linked list of cookies we know of */ | ||||||
|   struct Cookie *cookies; |   struct Cookie *cookies; | ||||||
|  |  | ||||||
|   char *filename; /* file we read from/write to */ |   char *filename;  /* file we read from/write to */ | ||||||
|   bool running;   /* state info, for cookie adding information */ |   bool running;    /* state info, for cookie adding information */ | ||||||
|   long numcookies; /* number of cookies in the "jar" */ |   long numcookies; /* number of cookies in the "jar" */ | ||||||
|  |   bool newsession; /* new session, discard session cookies on load */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* This is the maximum line length we accept for a cookie line */ | /* This is the maximum line length we accept for a cookie line */ | ||||||
| @@ -75,7 +76,7 @@ struct CookieInfo { | |||||||
| struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line, | struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line, | ||||||
|                                char *domain); |                                char *domain); | ||||||
|  |  | ||||||
| struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *); | struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *, bool); | ||||||
| struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); | struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); | ||||||
| void Curl_cookie_freelist(struct Cookie *); | void Curl_cookie_freelist(struct Cookie *); | ||||||
| void Curl_cookie_cleanup(struct CookieInfo *); | void Curl_cookie_cleanup(struct CookieInfo *); | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -238,7 +238,7 @@ CURLcode curl_easy_perform(CURL *curl) | |||||||
|       data->hostcache = Curl_global_host_cache_get(); |       data->hostcache = Curl_global_host_cache_get(); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       data->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo); |       data->hostcache = Curl_hash_alloc(7, Curl_freeaddrinfo); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -249,7 +249,7 @@ void curl_easy_cleanup(CURL *curl) | |||||||
| { | { | ||||||
|   struct SessionHandle *data = (struct SessionHandle *)curl; |   struct SessionHandle *data = (struct SessionHandle *)curl; | ||||||
|   if (!Curl_global_host_cache_use(data)) { |   if (!Curl_global_host_cache_use(data)) { | ||||||
|     curl_hash_destroy(data->hostcache); |     Curl_hash_destroy(data->hostcache); | ||||||
|   } |   } | ||||||
|   Curl_close(data); |   Curl_close(data); | ||||||
| } | } | ||||||
| @@ -312,7 +312,8 @@ CURL *curl_easy_duphandle(CURL *incurl) | |||||||
|     /* If cookies are enabled in the parent handle, we enable them |     /* If cookies are enabled in the parent handle, we enable them | ||||||
|        in the clone as well! */ |        in the clone as well! */ | ||||||
|     outcurl->cookies = Curl_cookie_init(data->cookies->filename, |     outcurl->cookies = Curl_cookie_init(data->cookies->filename, | ||||||
|                                         outcurl->cookies); |                                         outcurl->cookies, | ||||||
|  |                                         data->set.cookiesession); | ||||||
|  |  | ||||||
|   /* duplicate all values in 'change' */ |   /* duplicate all values in 'change' */ | ||||||
|   if(data->change.url) { |   if(data->change.url) { | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -140,7 +140,7 @@ CURLcode Curl_file(struct connectdata *conn) | |||||||
|   */ |   */ | ||||||
|   CURLcode res = CURLE_OK; |   CURLcode res = CURLE_OK; | ||||||
|   struct stat statbuf; |   struct stat statbuf; | ||||||
|   ssize_t expected_size=-1; |   double expected_size=-1; | ||||||
|   ssize_t nread; |   ssize_t nread; | ||||||
|   struct SessionHandle *data = conn->data; |   struct SessionHandle *data = conn->data; | ||||||
|   char *buf = data->state.buffer; |   char *buf = data->state.buffer; | ||||||
| @@ -155,7 +155,7 @@ CURLcode Curl_file(struct connectdata *conn) | |||||||
| /*VMS?? -- This only works reliable for STREAMLF files */ | /*VMS?? -- This only works reliable for STREAMLF files */ | ||||||
|   if( -1 != fstat(fd, &statbuf)) { |   if( -1 != fstat(fd, &statbuf)) { | ||||||
|     /* we could stat it, then read out the size */ |     /* we could stat it, then read out the size */ | ||||||
|     expected_size = statbuf.st_size; |     expected_size = (double)statbuf.st_size; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* The following is a shortcut implementation of file reading |   /* The following is a shortcut implementation of file reading | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
							
								
								
									
										218
									
								
								lib/formdata.c
									
									
									
									
									
								
							
							
						
						
									
										218
									
								
								lib/formdata.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -171,8 +171,8 @@ static void GetStr(char **string, | |||||||
|  |  | ||||||
| static | static | ||||||
| int FormParse(char *input, | int FormParse(char *input, | ||||||
| 	      struct HttpPost **httppost, | 	      struct curl_httppost **httppost, | ||||||
| 	      struct HttpPost **last_post) | 	      struct curl_httppost **last_post) | ||||||
| { | { | ||||||
|   /* nextarg MUST be a string in the format 'name=contents' and we'll |   /* nextarg MUST be a string in the format 'name=contents' and we'll | ||||||
|      build a linked list with the info */ |      build a linked list with the info */ | ||||||
| @@ -186,8 +186,8 @@ int FormParse(char *input, | |||||||
|   char *prevtype = NULL; |   char *prevtype = NULL; | ||||||
|   char *sep; |   char *sep; | ||||||
|   char *sep2; |   char *sep2; | ||||||
|   struct HttpPost *post; |   struct curl_httppost *post; | ||||||
|   struct HttpPost *subpost; /* a sub-node */ |   struct curl_httppost *subpost; /* a sub-node */ | ||||||
|   unsigned int i; |   unsigned int i; | ||||||
|  |  | ||||||
|   /* Preallocate contents to the length of input to make sure we don't |   /* Preallocate contents to the length of input to make sure we don't | ||||||
| @@ -296,9 +296,9 @@ int FormParse(char *input, | |||||||
| 	  /* For the first file name, we allocate and initiate the main list | 	  /* For the first file name, we allocate and initiate the main list | ||||||
| 	     node */ | 	     node */ | ||||||
|  |  | ||||||
| 	  post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); | 	  post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); | ||||||
| 	  if(post) { | 	  if(post) { | ||||||
| 	    memset(post, 0, sizeof(struct HttpPost)); | 	    memset(post, 0, sizeof(struct curl_httppost)); | ||||||
| 	    GetStr(&post->name, name);      /* get the name */ | 	    GetStr(&post->name, name);      /* get the name */ | ||||||
| 	    GetStr(&post->contents, contp); /* get the contents */ | 	    GetStr(&post->contents, contp); /* get the contents */ | ||||||
|             post->contentslength = 0; |             post->contentslength = 0; | ||||||
| @@ -320,9 +320,10 @@ int FormParse(char *input, | |||||||
| 	else { | 	else { | ||||||
| 	  /* we add a file name to the previously allocated node, known as | 	  /* we add a file name to the previously allocated node, known as | ||||||
|              'post' now */ |              'post' now */ | ||||||
| 	  subpost =(struct HttpPost *)malloc(sizeof(struct HttpPost)); | 	  subpost =(struct curl_httppost *) | ||||||
|  |             malloc(sizeof(struct curl_httppost)); | ||||||
| 	  if(subpost) { | 	  if(subpost) { | ||||||
| 	     memset(subpost, 0, sizeof(struct HttpPost)); | 	     memset(subpost, 0, sizeof(struct curl_httppost)); | ||||||
| 	     GetStr(&subpost->name, name);      /* get the name */ | 	     GetStr(&subpost->name, name);      /* get the name */ | ||||||
| 	     GetStr(&subpost->contents, contp); /* get the contents */ | 	     GetStr(&subpost->contents, contp); /* get the contents */ | ||||||
|              subpost->contentslength = 0; |              subpost->contentslength = 0; | ||||||
| @@ -342,9 +343,9 @@ int FormParse(char *input, | |||||||
|       } while(sep && *sep); /* loop if there's another file name */ |       } while(sep && *sep); /* loop if there's another file name */ | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); |       post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); | ||||||
|       if(post) { |       if(post) { | ||||||
| 	memset(post, 0, sizeof(struct HttpPost)); | 	memset(post, 0, sizeof(struct curl_httppost)); | ||||||
| 	GetStr(&post->name, name);      /* get the name */ | 	GetStr(&post->name, name);      /* get the name */ | ||||||
| 	if( contp[0]=='<' ) { | 	if( contp[0]=='<' ) { | ||||||
| 	  GetStr(&post->contents, contp+1); /* get the contents */ | 	  GetStr(&post->contents, contp+1); /* get the contents */ | ||||||
| @@ -378,8 +379,8 @@ int FormParse(char *input, | |||||||
| } | } | ||||||
|  |  | ||||||
| int curl_formparse(char *input, | int curl_formparse(char *input, | ||||||
|                    struct HttpPost **httppost, |                    struct curl_httppost **httppost, | ||||||
|                    struct HttpPost **last_post) |                    struct curl_httppost **last_post) | ||||||
| { | { | ||||||
|   return FormParse(input, httppost, last_post); |   return FormParse(input, httppost, last_post); | ||||||
| } | } | ||||||
| @@ -394,27 +395,28 @@ int curl_formparse(char *input, | |||||||
|  * Returns newly allocated HttpPost on success and NULL if malloc failed. |  * Returns newly allocated HttpPost on success and NULL if malloc failed. | ||||||
|  * |  * | ||||||
|  ***************************************************************************/ |  ***************************************************************************/ | ||||||
| static struct HttpPost * AddHttpPost(char * name, | static struct curl_httppost * | ||||||
|                                      long namelength, | AddHttpPost(char * name, long namelength, | ||||||
|                                      char * value, |             char * value, long contentslength, | ||||||
|                                      long contentslength, |             char *contenttype, | ||||||
|                                      char *contenttype, |             long flags, | ||||||
|                                      long flags, |             struct curl_slist* contentHeader, | ||||||
|                                      struct curl_slist* contentHeader, |             char *showfilename, | ||||||
|                                      struct HttpPost *parent_post, |             struct curl_httppost *parent_post, | ||||||
|                                      struct HttpPost **httppost, |             struct curl_httppost **httppost, | ||||||
|                                      struct HttpPost **last_post) |             struct curl_httppost **last_post) | ||||||
| { | { | ||||||
|   struct HttpPost *post; |   struct curl_httppost *post; | ||||||
|   post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); |   post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost)); | ||||||
|   if(post) { |   if(post) { | ||||||
|     memset(post, 0, sizeof(struct HttpPost)); |     memset(post, 0, sizeof(struct curl_httppost)); | ||||||
|     post->name = name; |     post->name = name; | ||||||
|     post->namelength = name?(namelength?namelength:(long)strlen(name)):0; |     post->namelength = name?(namelength?namelength:(long)strlen(name)):0; | ||||||
|     post->contents = value; |     post->contents = value; | ||||||
|     post->contentslength = contentslength; |     post->contentslength = contentslength; | ||||||
|     post->contenttype = contenttype; |     post->contenttype = contenttype; | ||||||
|     post->contentheader = contentHeader; |     post->contentheader = contentHeader; | ||||||
|  |     post->showfilename = showfilename; | ||||||
|     post->flags = flags; |     post->flags = flags; | ||||||
|   } |   } | ||||||
|   else |   else | ||||||
| @@ -627,17 +629,17 @@ typedef enum { | |||||||
| } FORMcode; | } FORMcode; | ||||||
|  |  | ||||||
| static | static | ||||||
| FORMcode FormAdd(struct HttpPost **httppost, | FORMcode FormAdd(struct curl_httppost **httppost, | ||||||
|                  struct HttpPost **last_post, |                  struct curl_httppost **last_post, | ||||||
|                  va_list params) |                  va_list params) | ||||||
| { | { | ||||||
|   FormInfo *first_form, *current_form, *form; |   FormInfo *first_form, *current_form, *form; | ||||||
|   FORMcode return_value = FORMADD_OK; |   FORMcode return_value = FORMADD_OK; | ||||||
|   const char *prevtype = NULL; |   const char *prevtype = NULL; | ||||||
|   struct HttpPost *post = NULL; |   struct curl_httppost *post = NULL; | ||||||
|   CURLformoption option; |   CURLformoption option; | ||||||
|   struct curl_forms *forms = NULL; |   struct curl_forms *forms = NULL; | ||||||
|   const char *array_value; /* value read from an array */ |   char *array_value; /* value read from an array */ | ||||||
|  |  | ||||||
|   /* This is a state variable, that if TRUE means that we're parsing an |   /* This is a state variable, that if TRUE means that we're parsing an | ||||||
|      array that we got passed to us. If FALSE we're parsing the input |      array that we got passed to us. If FALSE we're parsing the input | ||||||
| @@ -668,7 +670,7 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|     if ( array_state ) { |     if ( array_state ) { | ||||||
|       /* get the upcoming option from the given array */ |       /* get the upcoming option from the given array */ | ||||||
|       option = forms->option; |       option = forms->option; | ||||||
|       array_value = forms->value; |       array_value = (char *)forms->value; | ||||||
|  |  | ||||||
|       forms++; /* advance this to next entry */ |       forms++; /* advance this to next entry */ | ||||||
|       if (CURLFORM_END == option) { |       if (CURLFORM_END == option) { | ||||||
| @@ -676,16 +678,6 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|         array_state = FALSE; |         array_state = FALSE; | ||||||
|         continue; |         continue; | ||||||
|       } |       } | ||||||
|       else { |  | ||||||
|         /* check that the option is OK in an array */ |  | ||||||
|  |  | ||||||
|         /* Daniel's note: do we really need to do this? */ |  | ||||||
|         if ( (option <= CURLFORM_ARRAY_START) || |  | ||||||
|              (option >= CURLFORM_ARRAY_END) ) { |  | ||||||
|           return_value = FORMADD_ILLEGAL_ARRAY; |  | ||||||
|           break; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       /* This is not array-state, get next option */ |       /* This is not array-state, get next option */ | ||||||
| @@ -696,11 +688,16 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|  |  | ||||||
|     switch (option) { |     switch (option) { | ||||||
|     case CURLFORM_ARRAY: |     case CURLFORM_ARRAY: | ||||||
|       forms = va_arg(params, struct curl_forms *); |       if(array_state) | ||||||
|       if (forms) |         /* we don't support an array from within an array */ | ||||||
|         array_state = TRUE; |         return_value = FORMADD_ILLEGAL_ARRAY; | ||||||
|       else |       else { | ||||||
|         return_value = FORMADD_NULL; |         forms = va_arg(params, struct curl_forms *); | ||||||
|  |         if (forms) | ||||||
|  |           array_state = TRUE; | ||||||
|  |         else | ||||||
|  |           return_value = FORMADD_NULL; | ||||||
|  |       } | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|       /* |       /* | ||||||
| @@ -712,7 +709,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       if (current_form->name) |       if (current_form->name) | ||||||
|         return_value = FORMADD_OPTION_TWICE; |         return_value = FORMADD_OPTION_TWICE; | ||||||
|       else { |       else { | ||||||
|         char *name = va_arg(params, char *); |         char *name = array_state? | ||||||
|  |           array_value:va_arg(params, char *); | ||||||
|         if (name) |         if (name) | ||||||
|           current_form->name = name; /* store for the moment */ |           current_form->name = name; /* store for the moment */ | ||||||
|         else |         else | ||||||
| @@ -723,7 +721,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       if (current_form->namelength) |       if (current_form->namelength) | ||||||
|         return_value = FORMADD_OPTION_TWICE; |         return_value = FORMADD_OPTION_TWICE; | ||||||
|       else |       else | ||||||
|         current_form->namelength = va_arg(params, long); |         current_form->namelength = | ||||||
|  |           array_state?(long)array_value:va_arg(params, long); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|       /* |       /* | ||||||
| @@ -735,7 +734,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       if (current_form->value) |       if (current_form->value) | ||||||
|         return_value = FORMADD_OPTION_TWICE; |         return_value = FORMADD_OPTION_TWICE; | ||||||
|       else { |       else { | ||||||
|         char *value = va_arg(params, char *); |         char *value = | ||||||
|  |           array_state?array_value:va_arg(params, char *); | ||||||
|         if (value) |         if (value) | ||||||
|           current_form->value = value; /* store for the moment */ |           current_form->value = value; /* store for the moment */ | ||||||
|         else |         else | ||||||
| @@ -746,7 +746,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       if (current_form->contentslength) |       if (current_form->contentslength) | ||||||
|         return_value = FORMADD_OPTION_TWICE; |         return_value = FORMADD_OPTION_TWICE; | ||||||
|       else |       else | ||||||
|         current_form->contentslength = va_arg(params, long); |         current_form->contentslength = | ||||||
|  |           array_state?(long)array_value:va_arg(params, long); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|       /* Get contents from a given file name */ |       /* Get contents from a given file name */ | ||||||
| @@ -754,7 +755,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       if (current_form->flags != 0) |       if (current_form->flags != 0) | ||||||
|         return_value = FORMADD_OPTION_TWICE; |         return_value = FORMADD_OPTION_TWICE; | ||||||
|       else { |       else { | ||||||
|         char *filename = va_arg(params, char *); |         char *filename = array_state? | ||||||
|  |           array_value:va_arg(params, char *); | ||||||
|         if (filename) { |         if (filename) { | ||||||
|           current_form->value = strdup(filename); |           current_form->value = strdup(filename); | ||||||
|           current_form->flags |= HTTPPOST_READFILE; |           current_form->flags |= HTTPPOST_READFILE; | ||||||
| @@ -767,11 +769,9 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       /* We upload a file */ |       /* We upload a file */ | ||||||
|     case CURLFORM_FILE: |     case CURLFORM_FILE: | ||||||
|       { |       { | ||||||
|         const char *filename = NULL; |         char *filename = array_state?array_value: | ||||||
|         if (array_state) |           va_arg(params, char *); | ||||||
|           filename = array_value; |  | ||||||
|         else |  | ||||||
|           filename = va_arg(params, const char *); |  | ||||||
|         if (current_form->value) { |         if (current_form->value) { | ||||||
|           if (current_form->flags & HTTPPOST_FILENAME) { |           if (current_form->flags & HTTPPOST_FILENAME) { | ||||||
|             if (filename) { |             if (filename) { | ||||||
| @@ -796,11 +796,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       } |       } | ||||||
|     case CURLFORM_CONTENTTYPE: |     case CURLFORM_CONTENTTYPE: | ||||||
|       { |       { | ||||||
| 	const char *contenttype = NULL; | 	char *contenttype = | ||||||
|         if (array_state) |           array_state?array_value:va_arg(params, char *); | ||||||
|           contenttype = array_value; |  | ||||||
|         else |  | ||||||
|           contenttype = va_arg(params, const char *); |  | ||||||
|         if (current_form->contenttype) { |         if (current_form->contenttype) { | ||||||
|           if (current_form->flags & HTTPPOST_FILENAME) { |           if (current_form->flags & HTTPPOST_FILENAME) { | ||||||
|             if (contenttype) { |             if (contenttype) { | ||||||
| @@ -825,11 +822,11 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|       } |       } | ||||||
|     case CURLFORM_CONTENTHEADER: |     case CURLFORM_CONTENTHEADER: | ||||||
|       { |       { | ||||||
|         struct curl_slist* list = NULL; |         /* this "cast increases required alignment of target type" but | ||||||
|         if( array_state ) |            we consider it OK anyway */ | ||||||
|           list = (struct curl_slist*)array_value; |         struct curl_slist* list = array_state? | ||||||
|         else |           (struct curl_slist*)array_value: | ||||||
|           list = va_arg(params,struct curl_slist*); |           va_arg(params, struct curl_slist*); | ||||||
|          |          | ||||||
|         if( current_form->contentheader ) |         if( current_form->contentheader ) | ||||||
|           return_value = FORMADD_OPTION_TWICE; |           return_value = FORMADD_OPTION_TWICE; | ||||||
| @@ -838,6 +835,16 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|          |          | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|  |     case CURLFORM_FILENAME: | ||||||
|  |       { | ||||||
|  |         char *filename = array_state?array_value: | ||||||
|  |           va_arg(params, char *); | ||||||
|  |         if( current_form->showfilename ) | ||||||
|  |           return_value = FORMADD_OPTION_TWICE; | ||||||
|  |         else | ||||||
|  |           current_form->showfilename = strdup(filename); | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|     default: |     default: | ||||||
|       return_value = FORMADD_UNKNOWN_OPTION; |       return_value = FORMADD_UNKNOWN_OPTION; | ||||||
|     } |     } | ||||||
| @@ -889,7 +896,7 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|         post = AddHttpPost(form->name, form->namelength, |         post = AddHttpPost(form->name, form->namelength, | ||||||
|                            form->value, form->contentslength, |                            form->value, form->contentslength, | ||||||
|                            form->contenttype, form->flags, |                            form->contenttype, form->flags, | ||||||
|                            form->contentheader, |                            form->contentheader, form->showfilename, | ||||||
|                            post, httppost, |                            post, httppost, | ||||||
|                            last_post); |                            last_post); | ||||||
|          |          | ||||||
| @@ -915,8 +922,8 @@ FORMcode FormAdd(struct HttpPost **httppost, | |||||||
|   return return_value; |   return return_value; | ||||||
| } | } | ||||||
|  |  | ||||||
| int curl_formadd(struct HttpPost **httppost, | int curl_formadd(struct curl_httppost **httppost, | ||||||
|                  struct HttpPost **last_post, |                  struct curl_httppost **last_post, | ||||||
|                  ...) |                  ...) | ||||||
| { | { | ||||||
|   va_list arg; |   va_list arg; | ||||||
| @@ -975,8 +982,8 @@ char *Curl_FormBoundary(void) | |||||||
| 			      the same form won't be identical */ | 			      the same form won't be identical */ | ||||||
|   int i; |   int i; | ||||||
|  |  | ||||||
|   static char table64[]= |   static char table62[]= | ||||||
|     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||||||
|  |  | ||||||
|   retstring = (char *)malloc(BOUNDARY_LENGTH); |   retstring = (char *)malloc(BOUNDARY_LENGTH); | ||||||
|  |  | ||||||
| @@ -988,7 +995,7 @@ char *Curl_FormBoundary(void) | |||||||
|   strcpy(retstring, "curl"); /* bonus commercials 8*) */ |   strcpy(retstring, "curl"); /* bonus commercials 8*) */ | ||||||
|  |  | ||||||
|   for(i=4; i<(BOUNDARY_LENGTH-1); i++) { |   for(i=4; i<(BOUNDARY_LENGTH-1); i++) { | ||||||
|     retstring[i] = table64[rand()%64]; |     retstring[i] = table62[rand()%62]; | ||||||
|   } |   } | ||||||
|   retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */ |   retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */ | ||||||
|  |  | ||||||
| @@ -1009,9 +1016,9 @@ void Curl_formclean(struct FormData *form) | |||||||
| } | } | ||||||
|  |  | ||||||
| /* external function to free up a whole form post chain */ | /* external function to free up a whole form post chain */ | ||||||
| void curl_formfree(struct HttpPost *form) | void curl_formfree(struct curl_httppost *form) | ||||||
| { | { | ||||||
|   struct HttpPost *next; |   struct curl_httppost *next; | ||||||
|  |  | ||||||
|   if(!form) |   if(!form) | ||||||
|     /* no form to free, just get out of this */ |     /* no form to free, just get out of this */ | ||||||
| @@ -1030,27 +1037,31 @@ void curl_formfree(struct HttpPost *form) | |||||||
|       free(form->contents); /* free the contents */ |       free(form->contents); /* free the contents */ | ||||||
|     if(form->contenttype) |     if(form->contenttype) | ||||||
|       free(form->contenttype); /* free the content type */ |       free(form->contenttype); /* free the content type */ | ||||||
|  |     if(form->showfilename) | ||||||
|  |       free(form->showfilename); /* free the faked file name */ | ||||||
|     free(form);       /* free the struct */ |     free(form);       /* free the struct */ | ||||||
|  |  | ||||||
|   } while((form=next)); /* continue */ |   } while((form=next)); /* continue */ | ||||||
| } | } | ||||||
|  |  | ||||||
| struct FormData *Curl_getFormData(struct HttpPost *post, | CURLcode Curl_getFormData(struct FormData **finalform, | ||||||
|                                   int *sizep) |                           struct curl_httppost *post, | ||||||
|  |                           int *sizep) | ||||||
| { | { | ||||||
|   struct FormData *form = NULL; |   struct FormData *form = NULL; | ||||||
|   struct FormData *firstform; |   struct FormData *firstform; | ||||||
|  |   struct curl_httppost *file; | ||||||
|   struct HttpPost *file; |   CURLcode result = CURLE_OK; | ||||||
|  |  | ||||||
|   int size =0; |   int size =0; | ||||||
|   char *boundary; |   char *boundary; | ||||||
|   char *fileboundary=NULL; |   char *fileboundary=NULL; | ||||||
|   struct curl_slist* curList; |   struct curl_slist* curList; | ||||||
|  |  | ||||||
|  |   *finalform=NULL; /* default form is empty */ | ||||||
|  |  | ||||||
|   if(!post) |   if(!post) | ||||||
|     return NULL; /* no input => no output! */ |     return result; /* no input => no output! */ | ||||||
|  |  | ||||||
|   boundary = Curl_FormBoundary(); |   boundary = Curl_FormBoundary(); | ||||||
|    |    | ||||||
| @@ -1093,16 +1104,25 @@ struct FormData *Curl_getFormData(struct HttpPost *post, | |||||||
|     file = post; |     file = post; | ||||||
|  |  | ||||||
|     do { |     do { | ||||||
|  |  | ||||||
|  |       /* If 'showfilename' is set, that is a faked name passed on to us | ||||||
|  |          to use to in the formpost. If that is not set, the actually used | ||||||
|  |          local file name should be added. */ | ||||||
|  |  | ||||||
|       if(post->more) { |       if(post->more) { | ||||||
| 	/* if multiple-file */ | 	/* if multiple-file */ | ||||||
| 	size += AddFormDataf(&form, | 	size += AddFormDataf(&form, | ||||||
| 			     "\r\n--%s\r\nContent-Disposition: attachment; filename=\"%s\"", | 			     "\r\n--%s\r\nContent-Disposition: " | ||||||
| 			     fileboundary, file->contents); |                              "attachment; filename=\"%s\"", | ||||||
|  | 			     fileboundary, | ||||||
|  |                              (file->showfilename?file->showfilename: | ||||||
|  |                               file->contents)); | ||||||
|       } |       } | ||||||
|       else if(post->flags & HTTPPOST_FILENAME) { |       else if(post->flags & HTTPPOST_FILENAME) { | ||||||
| 	size += AddFormDataf(&form, | 	size += AddFormDataf(&form, | ||||||
| 			     "; filename=\"%s\"", | 			     "; filename=\"%s\"", | ||||||
| 			     post->contents); | 			     (post->showfilename?post->showfilename: | ||||||
|  |                               post->contents)); | ||||||
|       } |       } | ||||||
|        |        | ||||||
|       if(file->contenttype) { |       if(file->contenttype) { | ||||||
| @@ -1148,20 +1168,24 @@ struct FormData *Curl_getFormData(struct HttpPost *post, | |||||||
| /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ | /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ | ||||||
| /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ | /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ | ||||||
| 	if(fileread) { | 	if(fileread) { | ||||||
| 	  while((nread = fread(buffer, 1, 1024, fileread))) { | 	  while((nread = fread(buffer, 1, 1024, fileread))) | ||||||
| 	    size += AddFormData(&form, | 	    size += AddFormData(&form, buffer, nread); | ||||||
| 				buffer, |  | ||||||
| 				nread); |  | ||||||
| 	  } |  | ||||||
|           if(fileread != stdin) |           if(fileread != stdin) | ||||||
|             fclose(fileread); |             fclose(fileread); | ||||||
| 	} | 	} | ||||||
|         else { |         else { | ||||||
|  | #if 0 | ||||||
|           /* File wasn't found, add a nothing field! */ |           /* File wasn't found, add a nothing field! */ | ||||||
| 	  size += AddFormData(&form, "", 0); | 	  size += AddFormData(&form, "", 0); | ||||||
|  | #endif | ||||||
|  |           Curl_formclean(firstform); | ||||||
|  |           free(boundary); | ||||||
|  |           *finalform = NULL; | ||||||
|  |           return CURLE_READ_ERROR; | ||||||
| 	} | 	} | ||||||
|       } |       } | ||||||
|  else { |       else { | ||||||
| 	/* include the contents we got */ | 	/* include the contents we got */ | ||||||
| 	size += AddFormData(&form, post->contents, post->contentslength); | 	size += AddFormData(&form, post->contents, post->contentslength); | ||||||
|       } |       } | ||||||
| @@ -1187,7 +1211,9 @@ struct FormData *Curl_getFormData(struct HttpPost *post, | |||||||
|  |  | ||||||
|   free(boundary); |   free(boundary); | ||||||
|  |  | ||||||
|   return firstform; |   *finalform=firstform; | ||||||
|  |  | ||||||
|  |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| int Curl_FormInit(struct Form *form, struct FormData *formdata ) | int Curl_FormInit(struct Form *form, struct FormData *formdata ) | ||||||
| @@ -1294,8 +1320,8 @@ int Curl_FormReadOneLine(char *buffer, | |||||||
|  |  | ||||||
| #ifdef _FORM_DEBUG | #ifdef _FORM_DEBUG | ||||||
| int FormAddTest(const char * errormsg, | int FormAddTest(const char * errormsg, | ||||||
|                  struct HttpPost **httppost, |                  struct curl_httppost **httppost, | ||||||
|                  struct HttpPost **last_post, |                  struct curl_httppost **last_post, | ||||||
|                  ...) |                  ...) | ||||||
| { | { | ||||||
|   int result; |   int result; | ||||||
| @@ -1341,8 +1367,8 @@ int main() | |||||||
|   int size; |   int size; | ||||||
|   int nread; |   int nread; | ||||||
|   char buffer[4096]; |   char buffer[4096]; | ||||||
|   struct HttpPost *httppost=NULL; |   struct curl_httppost *httppost=NULL; | ||||||
|   struct HttpPost *last_post=NULL; |   struct curl_httppost *last_post=NULL; | ||||||
|   struct curl_forms forms[4]; |   struct curl_forms forms[4]; | ||||||
|  |  | ||||||
|   struct FormData *form; |   struct FormData *form; | ||||||
| @@ -1451,9 +1477,9 @@ int main(int argc, char **argv) | |||||||
| #endif | #endif | ||||||
|   int i; |   int i; | ||||||
|   char *nextarg; |   char *nextarg; | ||||||
|   struct HttpPost *httppost=NULL; |   struct curl_httppost *httppost=NULL; | ||||||
|   struct HttpPost *last_post=NULL; |   struct curl_httppost *last_post=NULL; | ||||||
|   struct HttpPost *post; |   struct curl_httppost *post; | ||||||
|   int size; |   int size; | ||||||
|   int nread; |   int nread; | ||||||
|   char buffer[4096]; |   char buffer[4096]; | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -44,14 +44,19 @@ typedef struct FormInfo { | |||||||
|   long contentslength; |   long contentslength; | ||||||
|   char *contenttype; |   char *contenttype; | ||||||
|   long flags; |   long flags; | ||||||
|  |  | ||||||
|  |   char *showfilename; /* The file name to show. If not set, the actual | ||||||
|  |                          file name will be used */ | ||||||
|   struct curl_slist* contentheader; |   struct curl_slist* contentheader; | ||||||
|   struct FormInfo *more; |   struct FormInfo *more; | ||||||
| } FormInfo; | } FormInfo; | ||||||
|  |  | ||||||
| int Curl_FormInit(struct Form *form, struct FormData *formdata ); | int Curl_FormInit(struct Form *form, struct FormData *formdata ); | ||||||
|  |  | ||||||
| struct FormData *Curl_getFormData(struct HttpPost *post, | CURLcode | ||||||
|                                   int *size); | Curl_getFormData(struct FormData **, | ||||||
|  |                  struct HttpPost *post, | ||||||
|  |                  int *size); | ||||||
|  |  | ||||||
| /* fread() emulation */ | /* fread() emulation */ | ||||||
| int Curl_FormReader(char *buffer, | int Curl_FormReader(char *buffer, | ||||||
|   | |||||||
							
								
								
									
										99
									
								
								lib/ftp.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								lib/ftp.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -210,16 +210,6 @@ int Curl_GetFTPResponse(char *buf, | |||||||
|   if (ftpcode) |   if (ftpcode) | ||||||
|     *ftpcode = 0; /* 0 for errors */ |     *ftpcode = 0; /* 0 for errors */ | ||||||
|  |  | ||||||
|   if(data->set.timeout) { |  | ||||||
|     /* if timeout is requested, find out how much remaining time we have */ |  | ||||||
|     timeout = data->set.timeout - /* timeout time */ |  | ||||||
|       Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */ |  | ||||||
|     if(timeout <=0 ) { |  | ||||||
|       failf(data, "Transfer aborted due to timeout"); |  | ||||||
|       return -SELECT_TIMEOUT; /* already too little time */ |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   FD_ZERO (&readfd);		/* clear it */ |   FD_ZERO (&readfd);		/* clear it */ | ||||||
|   FD_SET (sockfd, &readfd);     /* read socket */ |   FD_SET (sockfd, &readfd);     /* read socket */ | ||||||
|  |  | ||||||
| @@ -235,11 +225,22 @@ int Curl_GetFTPResponse(char *buf, | |||||||
|   keepon=TRUE; |   keepon=TRUE; | ||||||
|  |  | ||||||
|   while((nread<BUFSIZE) && (keepon && !error)) { |   while((nread<BUFSIZE) && (keepon && !error)) { | ||||||
|     readfd = rkeepfd;		   /* set every lap */ |     /* check and reset timeout value every lap */ | ||||||
|     interval.tv_sec = timeout; |     if(data->set.timeout) { | ||||||
|     interval.tv_usec = 0; |       /* if timeout is requested, find out how much remaining time we have */ | ||||||
|  |       timeout = data->set.timeout - /* timeout time */ | ||||||
|  |         Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */ | ||||||
|  |       if(timeout <=0 ) { | ||||||
|  |         failf(data, "Transfer aborted due to timeout"); | ||||||
|  |         return -SELECT_TIMEOUT; /* already too little time */ | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if(!ftp->cache) { | ||||||
|  |       readfd = rkeepfd;		   /* set every lap */ | ||||||
|  |       interval.tv_sec = timeout; | ||||||
|  |       interval.tv_usec = 0; | ||||||
|  |  | ||||||
|     if(!ftp->cache) |  | ||||||
|       switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) { |       switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) { | ||||||
|       case -1: /* select() error, stop reading */ |       case -1: /* select() error, stop reading */ | ||||||
|         error = SELECT_ERROR; |         error = SELECT_ERROR; | ||||||
| @@ -253,6 +254,7 @@ int Curl_GetFTPResponse(char *buf, | |||||||
|         error = SELECT_OK; |         error = SELECT_OK; | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|  |     } | ||||||
|     if(SELECT_OK == error) { |     if(SELECT_OK == error) { | ||||||
|       /* |       /* | ||||||
|        * This code previously didn't use the kerberos sec_read() code |        * This code previously didn't use the kerberos sec_read() code | ||||||
| @@ -301,11 +303,8 @@ int Curl_GetFTPResponse(char *buf, | |||||||
|             CURLcode result; |             CURLcode result; | ||||||
|  |  | ||||||
|             /* output debug output if that is requested */ |             /* output debug output if that is requested */ | ||||||
|             if(data->set.verbose) { |             if(data->set.verbose) | ||||||
|               fputs("< ", data->set.err); |               Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline); | ||||||
|               fwrite(line_start, perline, 1, data->set.err); |  | ||||||
|               /* no need to output LF here, it is part of the data */ |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             /* |             /* | ||||||
|              * We pass all response-lines to the callback function registered |              * We pass all response-lines to the callback function registered | ||||||
| @@ -622,8 +621,10 @@ CURLcode Curl_ftp_done(struct connectdata *conn) | |||||||
|   CURLcode result=CURLE_OK; |   CURLcode result=CURLE_OK; | ||||||
|  |  | ||||||
|   if(data->set.upload) { |   if(data->set.upload) { | ||||||
|     if((-1 != data->set.infilesize) && (data->set.infilesize != *ftp->bytecountp)) { |     if((-1 != data->set.infilesize) && | ||||||
|       failf(data, "Wrote only partial file (%d out of %d bytes)", |        (data->set.infilesize != *ftp->bytecountp) && | ||||||
|  |        !data->set.crlf) { | ||||||
|  |       failf(data, "Uploaded unaligned file size (%d out of %d bytes)", | ||||||
|             *ftp->bytecountp, data->set.infilesize); |             *ftp->bytecountp, data->set.infilesize); | ||||||
|       return CURLE_PARTIAL_FILE; |       return CURLE_PARTIAL_FILE; | ||||||
|     } |     } | ||||||
| @@ -905,8 +906,10 @@ ftp_pasv_verbose(struct connectdata *conn, | |||||||
|   if(gethostbyaddr_r((char *) &address, |   if(gethostbyaddr_r((char *) &address, | ||||||
|                      sizeof(address), AF_INET, |                      sizeof(address), AF_INET, | ||||||
|                      (struct hostent *)hostent_buf, |                      (struct hostent *)hostent_buf, | ||||||
|                      hostent_buf + sizeof(*answer))) |                      (struct hostent_data *)(hostent_buf + sizeof(*answer)))) | ||||||
|     answer=NULL; |     answer=NULL; | ||||||
|  |   else | ||||||
|  |     answer=(struct hostent *)hostent_buf; | ||||||
|                             |                             | ||||||
| #  endif | #  endif | ||||||
| #  ifdef HAVE_GETHOSTBYADDR_R_7 | #  ifdef HAVE_GETHOSTBYADDR_R_7 | ||||||
| @@ -914,7 +917,7 @@ ftp_pasv_verbose(struct connectdata *conn, | |||||||
|   answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET, |   answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET, | ||||||
|                            (struct hostent *)bigbuf, |                            (struct hostent *)bigbuf, | ||||||
|                            hostent_buf + sizeof(*answer), |                            hostent_buf + sizeof(*answer), | ||||||
|                            sizeof(hostent_buf) - sizeof(*answer), |                            sizeof(bigbuf) - sizeof(*answer), | ||||||
|                            &h_errnop); |                            &h_errnop); | ||||||
| #  endif | #  endif | ||||||
| #  ifdef HAVE_GETHOSTBYADDR_R_8 | #  ifdef HAVE_GETHOSTBYADDR_R_8 | ||||||
| @@ -922,7 +925,7 @@ ftp_pasv_verbose(struct connectdata *conn, | |||||||
|   if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET, |   if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET, | ||||||
|                      (struct hostent *)hostent_buf, |                      (struct hostent *)hostent_buf, | ||||||
|                      hostent_buf + sizeof(*answer), |                      hostent_buf + sizeof(*answer), | ||||||
|                      sizeof(hostent_buf) - sizeof(*answer), |                      sizeof(bigbuf) - sizeof(*answer), | ||||||
|                      &answer, |                      &answer, | ||||||
|                      &h_errnop)) |                      &h_errnop)) | ||||||
|     answer=NULL; /* error */ |     answer=NULL; /* error */ | ||||||
| @@ -1204,19 +1207,19 @@ CURLcode ftp_use_port(struct connectdata *conn) | |||||||
|  |  | ||||||
|   if(data->set.ftpport) { |   if(data->set.ftpport) { | ||||||
|     if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) { |     if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) { | ||||||
|       h = Curl_resolv(data, myhost, 0, &hostdataptr); |       h = Curl_resolv(data, myhost, 0); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       int len = strlen(data->set.ftpport); |       int len = strlen(data->set.ftpport); | ||||||
|       if(len>1) |       if(len>1) | ||||||
|         h = Curl_resolv(data, data->set.ftpport, 0, &hostdataptr); |         h = Curl_resolv(data, data->set.ftpport, 0); | ||||||
|       if(h) |       if(h) | ||||||
|         strcpy(myhost, data->set.ftpport); /* buffer overflow risk */ |         strcpy(myhost, data->set.ftpport); /* buffer overflow risk */ | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   if(! *myhost) { |   if(! *myhost) { | ||||||
|     char *tmp_host = getmyhost(myhost, sizeof(myhost)); |     char *tmp_host = getmyhost(myhost, sizeof(myhost)); | ||||||
|     h=Curl_resolv(data, tmp_host, 0, &hostdataptr); |     h=Curl_resolv(data, tmp_host, 0); | ||||||
|   } |   } | ||||||
|   infof(data, "We connect from %s\n", myhost); |   infof(data, "We connect from %s\n", myhost); | ||||||
|    |    | ||||||
| @@ -1359,7 +1362,6 @@ CURLcode ftp_use_pasv(struct connectdata *conn) | |||||||
|   int modeoff; |   int modeoff; | ||||||
|   unsigned short connectport; /* the local port connect() should use! */ |   unsigned short connectport; /* the local port connect() should use! */ | ||||||
|   unsigned short newport; /* remote port, not necessary the local one */ |   unsigned short newport; /* remote port, not necessary the local one */ | ||||||
|   char *hostdataptr=NULL; |  | ||||||
|    |    | ||||||
|   /* newhost must be able to hold a full IP-style address in ASCII, which |   /* newhost must be able to hold a full IP-style address in ASCII, which | ||||||
|      in the IPv6 case means 5*8-1 = 39 letters */ |      in the IPv6 case means 5*8-1 = 39 letters */ | ||||||
| @@ -1449,18 +1451,21 @@ CURLcode ftp_use_pasv(struct connectdata *conn) | |||||||
|   if(data->change.proxy) { |   if(data->change.proxy) { | ||||||
|     /* |     /* | ||||||
|      * This is a tunnel through a http proxy and we need to connect to the |      * This is a tunnel through a http proxy and we need to connect to the | ||||||
|      * proxy again here. We already have the name info for it since the |      * proxy again here. | ||||||
|      * previous lookup. |      * | ||||||
|  |      * We don't want to rely on a former host lookup that might've expired | ||||||
|  |      * now, instead we remake the lookup here and now! | ||||||
|      */ |      */ | ||||||
|     addr = conn->hostaddr; |     addr = Curl_resolv(data, conn->proxyhost, conn->port); | ||||||
|     connectport = |     connectport = | ||||||
|       (unsigned short)conn->port; /* we connect to the proxy's port */     |       (unsigned short)conn->port; /* we connect to the proxy's port */     | ||||||
|  |  | ||||||
|   } |   } | ||||||
|   else { |   else { | ||||||
|     /* normal, direct, ftp connection */ |     /* normal, direct, ftp connection */ | ||||||
|     addr = Curl_resolv(data, newhostp, newport, &hostdataptr); |     addr = Curl_resolv(data, newhostp, newport); | ||||||
|     if(!addr) { |     if(!addr) { | ||||||
|       failf(data, "Can't resolve new host %s", newhost); |       failf(data, "Can't resolve new host %s:%d", newhostp, newport); | ||||||
|       return CURLE_FTP_CANT_GET_HOST; |       return CURLE_FTP_CANT_GET_HOST; | ||||||
|     } |     } | ||||||
|     connectport = newport; /* we connect to the remote port */ |     connectport = newport; /* we connect to the remote port */ | ||||||
| @@ -1475,7 +1480,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn) | |||||||
|   if((CURLE_OK == result) &&        |   if((CURLE_OK == result) &&        | ||||||
|      data->set.verbose) |      data->set.verbose) | ||||||
|     /* this just dumps information about this second connection */ |     /* this just dumps information about this second connection */ | ||||||
|     ftp_pasv_verbose(conn, conninfo, newhost, connectport); |     ftp_pasv_verbose(conn, conninfo, newhostp, connectport); | ||||||
|    |    | ||||||
|   if(CURLE_OK != result) |   if(CURLE_OK != result) | ||||||
|     return result; |     return result; | ||||||
| @@ -1483,7 +1488,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn) | |||||||
|   if (data->set.tunnel_thru_httpproxy) { |   if (data->set.tunnel_thru_httpproxy) { | ||||||
|     /* We want "seamless" FTP operations through HTTP proxy tunnel */ |     /* We want "seamless" FTP operations through HTTP proxy tunnel */ | ||||||
|     result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket, |     result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket, | ||||||
|                                          newhost, newport); |                                          newhostp, newport); | ||||||
|     if(CURLE_OK != result) |     if(CURLE_OK != result) | ||||||
|       return result; |       return result; | ||||||
|   } |   } | ||||||
| @@ -1504,7 +1509,7 @@ CURLcode ftp_perform(struct connectdata *conn) | |||||||
| { | { | ||||||
|   /* this is FTP and no proxy */ |   /* this is FTP and no proxy */ | ||||||
|   ssize_t nread; |   ssize_t nread; | ||||||
|   CURLcode result; |   CURLcode result=CURLE_OK; | ||||||
|   struct SessionHandle *data=conn->data; |   struct SessionHandle *data=conn->data; | ||||||
|   char *buf = data->state.buffer; /* this is our buffer */ |   char *buf = data->state.buffer; /* this is our buffer */ | ||||||
|  |  | ||||||
| @@ -1544,7 +1549,7 @@ CURLcode ftp_perform(struct connectdata *conn) | |||||||
|   /* If we have selected NOBODY and HEADER, it means that we only want file |   /* If we have selected NOBODY and HEADER, it means that we only want file | ||||||
|      information. Which in FTP can't be much more than the file size and |      information. Which in FTP can't be much more than the file size and | ||||||
|      date. */ |      date. */ | ||||||
|   if(data->set.no_body && data->set.include_header) { |   if(data->set.no_body && data->set.include_header && ftp->file) { | ||||||
|     /* The SIZE command is _not_ RFC 959 specified, and therefor many servers |     /* The SIZE command is _not_ RFC 959 specified, and therefor many servers | ||||||
|        may not support it! It is however the only way we have to get a file's |        may not support it! It is however the only way we have to get a file's | ||||||
|        size! */ |        size! */ | ||||||
| @@ -1618,6 +1623,12 @@ CURLcode ftp_perform(struct connectdata *conn) | |||||||
|     if(result) |     if(result) | ||||||
|       return result; |       return result; | ||||||
|  |  | ||||||
|  |     /* Send any PREQUOTE strings after transfer type is set? (Wesley Laxton)*/ | ||||||
|  |     if(data->set.prequote) { | ||||||
|  |       if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK) | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if(conn->resume_from) { |     if(conn->resume_from) { | ||||||
|       /* we're about to continue the uploading of a file */ |       /* we're about to continue the uploading of a file */ | ||||||
|       /* 1. get already existing file's size. We use the SIZE |       /* 1. get already existing file's size. We use the SIZE | ||||||
| @@ -1803,6 +1814,12 @@ CURLcode ftp_perform(struct connectdata *conn) | |||||||
|       if(result) |       if(result) | ||||||
|         return result; |         return result; | ||||||
|  |  | ||||||
|  |       /* Send any PREQUOTE strings after transfer type is set? (Wesley Laxton)*/ | ||||||
|  |       if(data->set.prequote) { | ||||||
|  |         if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK) | ||||||
|  |           return result; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       /* Attempt to get the size, it'll be useful in some cases: for resumed |       /* Attempt to get the size, it'll be useful in some cases: for resumed | ||||||
|          downloads and when talking to servers that don't give away the size |          downloads and when talking to servers that don't give away the size | ||||||
|          in the RETR response line. */ |          in the RETR response line. */ | ||||||
| @@ -2070,9 +2087,6 @@ CURLcode Curl_ftpsendf(struct connectdata *conn, | |||||||
|   vsnprintf(s, 250, fmt, ap); |   vsnprintf(s, 250, fmt, ap); | ||||||
|   va_end(ap); |   va_end(ap); | ||||||
|    |    | ||||||
|   if(conn->data->set.verbose) |  | ||||||
|     fprintf(conn->data->set.err, "> %s\n", s); |  | ||||||
|  |  | ||||||
|   strcat(s, "\r\n"); /* append a trailing CRLF */ |   strcat(s, "\r\n"); /* append a trailing CRLF */ | ||||||
|  |  | ||||||
|   bytes_written=0; |   bytes_written=0; | ||||||
| @@ -2085,6 +2099,9 @@ CURLcode Curl_ftpsendf(struct connectdata *conn, | |||||||
|     if(CURLE_OK != res) |     if(CURLE_OK != res) | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|  |     if(conn->data->set.verbose) | ||||||
|  |       Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written); | ||||||
|  |  | ||||||
|     if(bytes_written != write_len) { |     if(bytes_written != write_len) { | ||||||
|       write_len -= bytes_written; |       write_len -= bytes_written; | ||||||
|       sptr += bytes_written; |       sptr += bytes_written; | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -35,6 +35,11 @@ | |||||||
| #include	<stdlib.h> | #include	<stdlib.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | /* Make this the last #include */ | ||||||
|  | #ifdef MALLOCDEBUG | ||||||
|  | #include "memdebug.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * This is supposed to be called in the beginning of a permform() session |  * This is supposed to be called in the beginning of a permform() session | ||||||
|  * and should reset all session-info variables |  * and should reset all session-info variables | ||||||
| @@ -49,6 +54,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data) | |||||||
|   pro->t_pretransfer = 0; |   pro->t_pretransfer = 0; | ||||||
|   pro->t_starttransfer = 0; |   pro->t_starttransfer = 0; | ||||||
|   pro->timespent = 0; |   pro->timespent = 0; | ||||||
|  |   pro->t_redirect = 0; | ||||||
|  |  | ||||||
|   info->httpcode = 0; |   info->httpcode = 0; | ||||||
|   info->httpversion=0; |   info->httpversion=0; | ||||||
| @@ -143,6 +149,12 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) | |||||||
|   case CURLINFO_CONTENT_LENGTH_UPLOAD: |   case CURLINFO_CONTENT_LENGTH_UPLOAD: | ||||||
|     *param_doublep = data->progress.size_ul; |     *param_doublep = data->progress.size_ul; | ||||||
|     break; |     break; | ||||||
|  |   case CURLINFO_REDIRECT_TIME: | ||||||
|  |     *param_doublep =  data->progress.t_redirect; | ||||||
|  |     break; | ||||||
|  |   case CURLINFO_REDIRECT_COUNT: | ||||||
|  |     *param_longp = data->set.followlocation; | ||||||
|  |     break; | ||||||
|   case CURLINFO_CONTENT_TYPE: |   case CURLINFO_CONTENT_TYPE: | ||||||
|     *param_charp = data->info.contenttype; |     *param_charp = data->info.contenttype; | ||||||
|     break; |     break; | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /* ============================================================================ | /* ============================================================================ | ||||||
|  * Copyright (C) 1998 Angus Mackay. All rights reserved;  |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * Redistribution and use are freely permitted provided that: |  * Redistribution and use are freely permitted provided that: | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
|   | |||||||
							
								
								
									
										283
									
								
								lib/hash.c
									
									
									
									
									
								
							
							
						
						
									
										283
									
								
								lib/hash.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -34,55 +34,45 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* {{{ static unsigned long _hash_str (const char *, size_t) | ||||||
|  |  */ | ||||||
| static unsigned long | static unsigned long | ||||||
| curl_hash_str(const char *key, unsigned int key_length) | _hash_str (const char *key, size_t key_length) | ||||||
| { | { | ||||||
|   register unsigned long h = 0; |   char *end = (char *) key + key_length; | ||||||
|   register unsigned long g; |   unsigned long h = 5381; | ||||||
|   register char *p = (char *) key; |  | ||||||
|   register char *end = (char *) key + key_length; |  | ||||||
|  |  | ||||||
|   while (p < end) { |   while (key < end) { | ||||||
|     h = (h << 4) + *p++; |     h += h << 5; | ||||||
|     if ((g = (h & 0xF0000000))) { |     h ^= (unsigned long) *key++; | ||||||
|       h = h ^ (g >> 24); |  | ||||||
|       h = h ^ g; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return h; |   return h; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
| static unsigned long  | /* {{{ static void _hash_element_dtor (void *, void *) | ||||||
| curl_hash_num(unsigned long key) |  */ | ||||||
| { |  | ||||||
|   key += ~(key << 15); |  | ||||||
|   key ^= (key >> 10); |  | ||||||
|   key += (key << 3); |  | ||||||
|   key ^= (key >> 6); |  | ||||||
|   key += (key << 11); |  | ||||||
|   key ^= (key >> 16); |  | ||||||
|  |  | ||||||
|   return key; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void  | static void  | ||||||
| hash_element_dtor(void *u, void *ele) | _hash_element_dtor (void *user, void *element) | ||||||
| { | { | ||||||
|   curl_hash_element *e = (curl_hash_element *) ele;  |   curl_hash         *h = (curl_hash *) user; | ||||||
|   curl_hash         *h = (curl_hash *) u;  |   curl_hash_element *e = (curl_hash_element *) element; | ||||||
|  |  | ||||||
|   if (e->key.type == CURL_HASH_KEY_IS_STRING) { |   if (e->key) { | ||||||
|     free(e->key.value.str.val); |     free(e->key); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   h->dtor(e->ptr); |   h->dtor(e->ptr); | ||||||
|  |  | ||||||
|   free(e); |   free(e); | ||||||
|   e = NULL; |  | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ void curl_hash_init (curl_hash *, int, curl_hash_dtor) | ||||||
|  |  */ | ||||||
| void  | void  | ||||||
| curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) | Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) | ||||||
| { | { | ||||||
|   int i; |   int i; | ||||||
|  |  | ||||||
| @@ -91,116 +81,111 @@ curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) | |||||||
|   h->slots = slots;   |   h->slots = slots;   | ||||||
|  |  | ||||||
|   h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); |   h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); | ||||||
|   for (i = 0; i < h->slots; ++i) { |   for (i = 0; i < slots; ++i) { | ||||||
|     h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor); |     h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ curl_hash *curl_hash_alloc (int, curl_hash_dtor) | ||||||
|  |  */ | ||||||
| curl_hash * | curl_hash * | ||||||
| curl_hash_alloc(int slots, curl_hash_dtor dtor) | Curl_hash_alloc (int slots, curl_hash_dtor dtor) | ||||||
| { | { | ||||||
|   curl_hash *h; |   curl_hash *h; | ||||||
|  |  | ||||||
|   h = (curl_hash *)malloc(sizeof(curl_hash)); |   h = (curl_hash *) malloc(sizeof(curl_hash)); | ||||||
|   if(NULL == h) |   if (NULL == h) | ||||||
|     return NULL; |     return NULL; | ||||||
|  |  | ||||||
|   curl_hash_init(h, slots, dtor); |   Curl_hash_init(h, slots, dtor); | ||||||
|  |  | ||||||
|   return h; |   return h; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
| #define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \ | /* {{{ static int _hash_key_compare (char *, size_t, char *, size_t) | ||||||
|   ((__s_key ? curl_hash_str(__s_key, __s_key_len) : curl_hash_num(__n_key)) % (__h)->slots) |  */ | ||||||
|  |  | ||||||
| #define KEY_CREATE(__k, __s_key, __s_key_len, __n_key, __dup) \ |  | ||||||
|   if (__s_key) { \ |  | ||||||
|     if (__dup) { \ |  | ||||||
|       (__k)->value.str.val = (char *) malloc(__s_key_len); \ |  | ||||||
|       memcpy((__k)->value.str.val, __s_key, __s_key_len); \ |  | ||||||
|     } else { \ |  | ||||||
|       (__k)->value.str.val = __s_key; \ |  | ||||||
|     } \ |  | ||||||
|     (__k)->value.str.len = __s_key_len; \ |  | ||||||
|     (__k)->type = CURL_HASH_KEY_IS_STRING; \ |  | ||||||
|   } else { \ |  | ||||||
|     (__k)->value.num = __n_key; \ |  | ||||||
|     (__k)->type = CURL_HASH_KEY_IS_NUM; \ |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| #define MIN(a, b) (a > b ? b : a) |  | ||||||
|  |  | ||||||
| static int  | static int  | ||||||
| curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2) | _hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len) | ||||||
| { | { | ||||||
|   if (key1->type == CURL_HASH_KEY_IS_NUM) { |   if (key1_len == key2_len &&  | ||||||
|     if (key2->type == CURL_HASH_KEY_IS_STRING) |       *key1 == *key2 && | ||||||
|       return 0; |       memcmp(key1, key2, key1_len) == 0) { | ||||||
|  |     return 1; | ||||||
|     if (key1->value.num == key2->value.num) |  | ||||||
|       return 1; |  | ||||||
|   } else { |  | ||||||
|     if (key2->type == CURL_HASH_KEY_IS_NUM) |  | ||||||
|       return 0; |  | ||||||
|  |  | ||||||
|     if (memcmp(key1->value.str.val, key2->value.str.val,  |  | ||||||
|                MIN(key1->value.str.len, key2->value.str.len)) == 0) |  | ||||||
|       return 1; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
| int  | /* {{{ static int _mk_hash_element (curl_hash_element **, char *, size_t, const void *) | ||||||
| curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len,  |  */ | ||||||
|                         unsigned long num_key, const void *p) | static int | ||||||
|  | _mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void *p) | ||||||
| { | { | ||||||
|   curl_hash_element  *e; |   *e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); | ||||||
|   curl_hash_key       tmp; |   (*e)->key = strdup(key); | ||||||
|   curl_llist         *l;  |   (*e)->key_len = key_len; | ||||||
|   curl_llist_element *le; |   (*e)->ptr = (void *) p; | ||||||
|   int                slot; |  | ||||||
|  |  | ||||||
|   slot = FIND_SLOT(h, str_key, str_key_len, num_key); |   return 0; | ||||||
|   l = h->table[slot]; | } | ||||||
|   KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); | /* }}} */ | ||||||
|   for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { |  | ||||||
|     if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { | #define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots) | ||||||
|       curl_hash_element *to_update = CURL_LLIST_VALP(le); |  | ||||||
|       h->dtor(to_update->ptr); | #define FETCH_LIST \ | ||||||
|       to_update->ptr = (void *) p; |   curl_llist *l = h->table[find_slot(h, key, key_len)] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *) | ||||||
|  |  */ | ||||||
|  | int  | ||||||
|  | Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) | ||||||
|  | { | ||||||
|  |   curl_hash_element  *he; | ||||||
|  |   curl_llist_element *le; | ||||||
|  |   FETCH_LIST; | ||||||
|  |  | ||||||
|  |   for (le = CURL_LLIST_HEAD(l); | ||||||
|  |        le != NULL; | ||||||
|  |        le = CURL_LLIST_NEXT(le)) { | ||||||
|  |     he = (curl_hash_element *) CURL_LLIST_VALP(le); | ||||||
|  |     if (_hash_key_compare(he->key, he->key_len, key, key_len)) { | ||||||
|  |       h->dtor(he->ptr); | ||||||
|  |       he->ptr = (void *) p; | ||||||
|       return 1; |       return 1; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); |   if (_mk_hash_element(&he, key, key_len, p) != 0)  | ||||||
|   KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1); |     return 0; | ||||||
|   e->ptr = (void *) p; |  | ||||||
|  |  | ||||||
|   if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) { |   if (Curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) { | ||||||
|     ++h->size; |     ++h->size; | ||||||
|     return 1; |     return 1; | ||||||
|   } else { |  | ||||||
|     return 0; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ int curl_hash_delete (curl_hash *, char *, size_t) | ||||||
|  |  */ | ||||||
| int  | int  | ||||||
| curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,  | Curl_hash_delete(curl_hash *h, char *key, size_t key_len) | ||||||
|                           unsigned long num_key) |  | ||||||
| { | { | ||||||
|   curl_llist         *l; |   curl_hash_element  *he; | ||||||
|   curl_llist_element *le; |   curl_llist_element *le; | ||||||
|   curl_hash_key       tmp; |   FETCH_LIST; | ||||||
|   int                slot; |  | ||||||
|  |  | ||||||
|   slot = FIND_SLOT(h, str_key, str_key_len, num_key); |   for (le = CURL_LLIST_HEAD(l); | ||||||
|   l = h->table[slot]; |        le != NULL; | ||||||
|  |        le = CURL_LLIST_NEXT(le)) { | ||||||
|   KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); |     he = CURL_LLIST_VALP(le); | ||||||
|   for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { |     if (_hash_key_compare(he->key, he->key_len, key, key_len)) { | ||||||
|     if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { |       Curl_llist_remove(l, le, (void *) h); | ||||||
|       curl_llist_remove(l, le, (void *) h); |  | ||||||
|       --h->size; |       --h->size; | ||||||
|       return 1; |       return 1; | ||||||
|     } |     } | ||||||
| @@ -208,73 +193,111 @@ curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, | |||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ int curl_hash_find (curl_hash *, char *, size_t, void **) | ||||||
|  |  */ | ||||||
| int  | int  | ||||||
| curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,  | Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) | ||||||
|                         unsigned long num_key, void **p) |  | ||||||
| { | { | ||||||
|   curl_llist         *l; |  | ||||||
|   curl_llist_element *le; |   curl_llist_element *le; | ||||||
|   curl_hash_key       tmp; |   curl_hash_element  *he; | ||||||
|   int                slot; |   FETCH_LIST; | ||||||
|  |  | ||||||
|   slot = FIND_SLOT(h, str_key, str_key_len, num_key); |   for (le = CURL_LLIST_HEAD(l); | ||||||
|   l = h->table[slot]; |        le != NULL; | ||||||
|  |        le = CURL_LLIST_NEXT(le)) { | ||||||
|   KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); |     he = CURL_LLIST_VALP(le); | ||||||
|   for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { |     if (_hash_key_compare(he->key, he->key_len, key, key_len)) { | ||||||
|     if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { |       *p = he->ptr; | ||||||
|       *p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr; |  | ||||||
|       return 1; |       return 1; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ void curl_hash_apply (curl_hash *, void *, void (*)(void *, curl_hash_element *)) | ||||||
|  |  */ | ||||||
| void  | void  | ||||||
| curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)) | Curl_hash_apply(curl_hash *h, void *user, | ||||||
|  |                 void (*cb)(void *, curl_hash_element *)) | ||||||
| { | { | ||||||
|   curl_llist_element  *le; |   curl_llist_element  *le; | ||||||
|   int                  i; |   int                  i; | ||||||
|  |  | ||||||
|   for (i = 0; i < h->slots; ++i) { |   for (i = 0; i < h->slots; ++i) { | ||||||
|     for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) { |     for (le = CURL_LLIST_HEAD(h->table[i]); | ||||||
|  |          le != NULL; | ||||||
|  |          le = CURL_LLIST_NEXT(le)) { | ||||||
|       cb(user, (curl_hash_element *) CURL_LLIST_VALP(le)); |       cb(user, (curl_hash_element *) CURL_LLIST_VALP(le)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ void curl_hash_clean (curl_hash *) | ||||||
|  |  */ | ||||||
| void | void | ||||||
| curl_hash_clean(curl_hash *h) | Curl_hash_clean(curl_hash *h) | ||||||
| { | { | ||||||
|   int i; |   int i; | ||||||
|  |  | ||||||
|   for (i = 0; i < h->slots; ++i) { |   for (i = 0; i < h->slots; ++i) { | ||||||
|     curl_llist_destroy(h->table[i], (void *) h); |     Curl_llist_destroy(h->table[i], (void *) h); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   free(h->table); |   free(h->table); | ||||||
|   h->table = NULL; | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, | ||||||
|  |    int (*)(void *, void *)) | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | Curl_hash_clean_with_criterium(curl_hash *h, void *user, | ||||||
|  |                                int (*comp)(void *, void *)) | ||||||
|  | { | ||||||
|  |   curl_llist_element *le; | ||||||
|  |   curl_llist_element *lnext; | ||||||
|  |   int i; | ||||||
|  |  | ||||||
|  |   for (i = 0; i < h->slots; ++i) { | ||||||
|  |     le = CURL_LLIST_HEAD(h->table[i]); | ||||||
|  |     while(le != NULL) | ||||||
|  |       if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) { | ||||||
|  |         lnext = CURL_LLIST_NEXT(le); | ||||||
|  |         Curl_llist_remove(h->table[i], le, (void *) h); | ||||||
|  |         --h->size; | ||||||
|  |         le = lnext; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |         le = CURL_LLIST_NEXT(le); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t  | /* {{{ int curl_hash_count (curl_hash *) | ||||||
| curl_hash_count(curl_hash *h) |  */ | ||||||
|  | int  | ||||||
|  | Curl_hash_count(curl_hash *h) | ||||||
| { | { | ||||||
|   return h->size; |   return h->size; | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
|  | /* {{{ void curl_hash_destroy (curl_hash *) | ||||||
|  |  */ | ||||||
| void  | void  | ||||||
| curl_hash_destroy(curl_hash *h) | Curl_hash_destroy(curl_hash *h) | ||||||
| { | { | ||||||
|   if (!h) { |   if (!h) | ||||||
|     return; |     return; | ||||||
|   } |  | ||||||
|  |  | ||||||
|   curl_hash_clean(h); |   Curl_hash_clean(h); | ||||||
|   free(h); |   free(h); | ||||||
|   h = NULL; |  | ||||||
| } | } | ||||||
|  | /* }}} */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * local variables: |  * local variables: | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								lib/hash.h
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								lib/hash.h
									
									
									
									
									
								
							| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -29,9 +29,6 @@ | |||||||
|  |  | ||||||
| #include "llist.h" | #include "llist.h" | ||||||
|  |  | ||||||
| #define CURL_HASH_KEY_IS_STRING 0 |  | ||||||
| #define CURL_HASH_KEY_IS_NUM    1 |  | ||||||
|  |  | ||||||
| typedef void (*curl_hash_dtor)(void *); | typedef void (*curl_hash_dtor)(void *); | ||||||
|  |  | ||||||
| typedef struct _curl_hash { | typedef struct _curl_hash { | ||||||
| @@ -41,45 +38,32 @@ typedef struct _curl_hash { | |||||||
|   size_t           size; |   size_t           size; | ||||||
| } curl_hash; | } curl_hash; | ||||||
|  |  | ||||||
| typedef struct _curl_hash_key { |  | ||||||
|   union { |  | ||||||
|     struct { |  | ||||||
|       char *val; |  | ||||||
|       unsigned int len; |  | ||||||
|     } str; |  | ||||||
|  |  | ||||||
|     unsigned long num; |  | ||||||
|   } value; |  | ||||||
|  |  | ||||||
|   int type; |  | ||||||
| } curl_hash_key; |  | ||||||
|  |  | ||||||
| typedef struct _curl_hash_element { | typedef struct _curl_hash_element { | ||||||
|   curl_hash_key  key; |   void   *ptr; | ||||||
|   void          *ptr; |   char   *key; | ||||||
|  |   size_t  key_len; | ||||||
| } curl_hash_element; | } curl_hash_element; | ||||||
|  |  | ||||||
|  |  | ||||||
| void curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor); | void Curl_hash_init(curl_hash *, int, curl_hash_dtor); | ||||||
| curl_hash *curl_hash_alloc(int slots, curl_hash_dtor dtor); | curl_hash *Curl_hash_alloc(int, curl_hash_dtor); | ||||||
| int curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len,  | int Curl_hash_add(curl_hash *, char *, size_t, const void *); | ||||||
| 			     unsigned long num_key, const void *p); | int Curl_hash_delete(curl_hash *h, char *key, size_t key_len); | ||||||
| int curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,  | int Curl_hash_find(curl_hash *, char *, size_t, void **p); | ||||||
| 			       unsigned long num_key); | void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)); | ||||||
| int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,  | int Curl_hash_count(curl_hash *h); | ||||||
| 			     unsigned long num_key, void **p); | void Curl_hash_clean(curl_hash *h); | ||||||
| void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)); | void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *)); | ||||||
| size_t curl_hash_count(curl_hash *h); | void Curl_hash_destroy(curl_hash *h); | ||||||
| void curl_hash_clean(curl_hash *h); |  | ||||||
| void curl_hash_destroy(curl_hash *h); |  | ||||||
|  |  | ||||||
| #define curl_hash_find(h, key, key_len, p) curl_hash_extended_find(h, key, key_len, 0, p) | #define Curl_hash_update Curl_hash_add | ||||||
| #define curl_hash_delete(h, key, key_len) curl_hash_extended_delete(h, key, key_len, 0) |  | ||||||
| #define curl_hash_add(h, key, key_len, p) curl_hash_add_or_update(h, key, key_len, 0, p) |  | ||||||
| #define curl_hash_update curl_hash_add |  | ||||||
| #define curl_hash_index_find(h, key, p) curl_hash_extended_find(h, NULL, 0, key, p) |  | ||||||
| #define curl_hash_index_delete(h, key) curl_hash_extended_delete(h, NULL, 0, key) |  | ||||||
| #define curl_hash_index_add(h, key, p) curl_hash_add_or_update(h, NULL, 0, key, p) |  | ||||||
| #define curl_hash_index_update curl_hash_index_add |  | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * local variables: | ||||||
|  |  * eval: (load-file "../curl-mode.el") | ||||||
|  |  * end: | ||||||
|  |  * vim600: fdm=marker | ||||||
|  |  * vim: et sw=2 ts=2 sts=2 tw=78 | ||||||
|  |  */ | ||||||
|   | |||||||
							
								
								
									
										220
									
								
								lib/hostip.c
									
									
									
									
									
								
							
							
						
						
									
										220
									
								
								lib/hostip.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -79,7 +79,7 @@ static int host_cache_initialized; | |||||||
| void Curl_global_host_cache_init(void) | void Curl_global_host_cache_init(void) | ||||||
| { | { | ||||||
|   if (!host_cache_initialized) { |   if (!host_cache_initialized) { | ||||||
|     curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo); |     Curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo); | ||||||
|     host_cache_initialized = 1; |     host_cache_initialized = 1; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -92,7 +92,7 @@ curl_hash *Curl_global_host_cache_get(void) | |||||||
| void Curl_global_host_cache_dtor(void) | void Curl_global_host_cache_dtor(void) | ||||||
| { | { | ||||||
|   if (host_cache_initialized) { |   if (host_cache_initialized) { | ||||||
|     curl_hash_clean(&hostname_cache); |     Curl_hash_clean(&hostname_cache); | ||||||
|     host_cache_initialized = 0; |     host_cache_initialized = 0; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -152,6 +152,38 @@ _create_hostcache_id(char *server, int port, ssize_t *entry_len) | |||||||
|   return id; |   return id; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct hostcache_prune_data { | ||||||
|  |   int cache_timeout; | ||||||
|  |   int now; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | _curl_hostcache_timestamp_remove(void *datap, void *hc) | ||||||
|  | { | ||||||
|  |   struct hostcache_prune_data *data =  | ||||||
|  |     (struct hostcache_prune_data *) datap; | ||||||
|  |   struct curl_dns_cache_entry *c = (struct curl_dns_cache_entry *) hc; | ||||||
|  |    | ||||||
|  |   if (data->now - c->timestamp < data->cache_timeout) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | hostcache_prune(curl_hash *hostcache, int cache_timeout, int now) | ||||||
|  | { | ||||||
|  |   struct hostcache_prune_data user; | ||||||
|  |  | ||||||
|  |   user.cache_timeout = cache_timeout; | ||||||
|  |   user.now = now; | ||||||
|  |    | ||||||
|  |   Curl_hash_clean_with_criterium(hostcache,  | ||||||
|  |                                  (void *) &user,  | ||||||
|  |                                  _curl_hostcache_timestamp_remove); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Macro to save redundant free'ing of entry_id */ | /* Macro to save redundant free'ing of entry_id */ | ||||||
| #define _hostcache_return(__v) \ | #define _hostcache_return(__v) \ | ||||||
| { \ | { \ | ||||||
| @@ -161,51 +193,50 @@ _create_hostcache_id(char *server, int port, ssize_t *entry_len) | |||||||
|  |  | ||||||
| Curl_addrinfo *Curl_resolv(struct SessionHandle *data, | Curl_addrinfo *Curl_resolv(struct SessionHandle *data, | ||||||
|                            char *hostname, |                            char *hostname, | ||||||
|                            int port, |                            int port) | ||||||
|                            char **bufp) |  | ||||||
| { | { | ||||||
|   char *entry_id = NULL; |   char *entry_id = NULL; | ||||||
|   struct curl_dns_cache_entry *p = NULL; |   struct curl_dns_cache_entry *p = NULL; | ||||||
|   ssize_t entry_len; |   ssize_t entry_len; | ||||||
|   time_t now; |   time_t now; | ||||||
|  |   char *bufp; | ||||||
|  |  | ||||||
|   /* If the host cache timeout is 0, we don't do DNS cach'ing |   /* If the host cache timeout is 0, we don't do DNS cach'ing | ||||||
|      so fall through */ |      so fall through */ | ||||||
|   if (data->set.dns_cache_timeout == 0) { |   if (data->set.dns_cache_timeout == 0) { | ||||||
|     return Curl_getaddrinfo(data, hostname, port, bufp); |     return Curl_getaddrinfo(data, hostname, port, &bufp); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   time(&now); | ||||||
|  |  | ||||||
|  |   /* Remove outdated entries from the hostcache */ | ||||||
|  |   hostcache_prune(data->hostcache,  | ||||||
|  |                   data->set.dns_cache_timeout,  | ||||||
|  |                   now); | ||||||
|  |  | ||||||
|   /* Create an entry id, based upon the hostname and port */ |   /* Create an entry id, based upon the hostname and port */ | ||||||
|   entry_len = strlen(hostname); |   entry_len = strlen(hostname); | ||||||
|   entry_id = _create_hostcache_id(hostname, port, &entry_len); |   entry_id = _create_hostcache_id(hostname, port, &entry_len); | ||||||
|   /* If we can't create the entry id, don't cache, just fall-through |   /* If we can't create the entry id, don't cache, just fall-through | ||||||
|      to the plain Curl_getaddrinfo() */ |      to the plain Curl_getaddrinfo() */ | ||||||
|   if (!entry_id) { |   if (!entry_id) { | ||||||
|     return Curl_getaddrinfo(data, hostname, port, bufp); |     return Curl_getaddrinfo(data, hostname, port, &bufp); | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   time(&now); |  | ||||||
|   /* See if its already in our dns cache */ |   /* See if its already in our dns cache */ | ||||||
|   if (entry_id && curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) { |   if (entry_id && | ||||||
|     /* Do we need to check for a cache timeout? */ |       Curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) { | ||||||
|     if (data->set.dns_cache_timeout != -1) { |     _hostcache_return(p->addr); | ||||||
|       /* Return if the entry has not timed out */ |  | ||||||
|       if ((now - p->timestamp) < data->set.dns_cache_timeout) { |  | ||||||
|         _hostcache_return(p->addr); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       _hostcache_return(p->addr); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* Create a new cache entry */ |   /* Create a new cache entry */ | ||||||
|   p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry)); |   p = (struct curl_dns_cache_entry *) | ||||||
|  |     malloc(sizeof(struct curl_dns_cache_entry)); | ||||||
|   if (!p) { |   if (!p) { | ||||||
|    _hostcache_return(NULL); |    _hostcache_return(NULL); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   p->addr = Curl_getaddrinfo(data, hostname, port, bufp); |   p->addr = Curl_getaddrinfo(data, hostname, port, &bufp); | ||||||
|   if (!p->addr) { |   if (!p->addr) { | ||||||
|     free(p); |     free(p); | ||||||
|     _hostcache_return(NULL); |     _hostcache_return(NULL); | ||||||
| @@ -213,7 +244,7 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data, | |||||||
|   p->timestamp = now; |   p->timestamp = now; | ||||||
|  |  | ||||||
|   /* Save it in our host cache */ |   /* Save it in our host cache */ | ||||||
|   curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p); |   Curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p); | ||||||
|  |  | ||||||
|   _hostcache_return(p->addr); |   _hostcache_return(p->addr); | ||||||
| } | } | ||||||
| @@ -291,9 +322,23 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
|   struct addrinfo hints, *res; |   struct addrinfo hints, *res; | ||||||
|   int error; |   int error; | ||||||
|   char sbuf[NI_MAXSERV]; |   char sbuf[NI_MAXSERV]; | ||||||
|  |   int s, pf = PF_UNSPEC; | ||||||
|  |  | ||||||
|  |   /* see if we have an IPv6 stack */ | ||||||
|  |   s = socket(PF_INET6, SOCK_DGRAM, 0); | ||||||
|  |   if (s < 0) | ||||||
|  |     /* Some non-IPv6 stacks have been found to make very slow name resolves | ||||||
|  |      * when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if | ||||||
|  |      * the stack seems to be a non-ipv6 one. */ | ||||||
|  |     pf = PF_INET; | ||||||
|  |   else | ||||||
|  |     /* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest | ||||||
|  |      * possible checks. And close the socket again. | ||||||
|  |      */ | ||||||
|  |     sclose(s); | ||||||
|   |   | ||||||
|   memset(&hints, 0, sizeof(hints)); |   memset(&hints, 0, sizeof(hints)); | ||||||
|   hints.ai_family = PF_INET; |   hints.ai_family = pf; | ||||||
|   hints.ai_socktype = SOCK_STREAM; |   hints.ai_socktype = SOCK_STREAM; | ||||||
|   hints.ai_flags = AI_CANONNAME; |   hints.ai_flags = AI_CANONNAME; | ||||||
|   snprintf(sbuf, sizeof(sbuf), "%d", port); |   snprintf(sbuf, sizeof(sbuf), "%d", port); | ||||||
| @@ -315,7 +360,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
|  * |  * | ||||||
|  * Keith McGuigan  |  * Keith McGuigan  | ||||||
|  * 10/3/2001 */ |  * 10/3/2001 */ | ||||||
| static struct hostent* pack_hostent(char* buf, struct hostent* orig) | static struct hostent* pack_hostent(char** buf, struct hostent* orig) | ||||||
| { | { | ||||||
|   char* bufptr; |   char* bufptr; | ||||||
|   struct hostent* copy; |   struct hostent* copy; | ||||||
| @@ -324,7 +369,7 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig) | |||||||
|   char* str; |   char* str; | ||||||
|   int len; |   int len; | ||||||
|  |  | ||||||
|   bufptr = buf; |   bufptr = *buf; | ||||||
|   copy = (struct hostent*)bufptr; |   copy = (struct hostent*)bufptr; | ||||||
|  |  | ||||||
|   bufptr += sizeof(struct hostent); |   bufptr += sizeof(struct hostent); | ||||||
| @@ -334,10 +379,12 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig) | |||||||
|   bufptr += len; |   bufptr += len; | ||||||
|  |  | ||||||
|   /* we align on even 64bit boundaries for safety */ |   /* we align on even 64bit boundaries for safety */ | ||||||
| #define MEMALIGN(x) (((unsigned long)(x)&0xfffffff8)+8) | #define MEMALIGN(x) ((x)+(8-(((unsigned long)(x))&0x7))) | ||||||
|  |  | ||||||
|   /* This must be aligned properly to work on many CPU architectures! */ |   /* This must be aligned properly to work on many CPU architectures! */ | ||||||
|   copy->h_aliases = (char**)MEMALIGN(bufptr); |   bufptr = MEMALIGN(bufptr); | ||||||
|  |    | ||||||
|  |   copy->h_aliases = (char**)bufptr; | ||||||
|  |  | ||||||
|   /* Figure out how many aliases there are */ |   /* Figure out how many aliases there are */ | ||||||
|   for (i = 0; orig->h_aliases[i] != NULL; ++i); |   for (i = 0; orig->h_aliases[i] != NULL; ++i); | ||||||
| @@ -359,7 +406,7 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig) | |||||||
|   copy->h_length = orig->h_length; |   copy->h_length = orig->h_length; | ||||||
|      |      | ||||||
|   /* align it for (at least) 32bit accesses */ |   /* align it for (at least) 32bit accesses */ | ||||||
|   bufptr = (char *)MEMALIGN(bufptr); |   bufptr = MEMALIGN(bufptr); | ||||||
|  |  | ||||||
|   copy->h_addr_list = (char**)bufptr; |   copy->h_addr_list = (char**)bufptr; | ||||||
|  |  | ||||||
| @@ -380,6 +427,7 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig) | |||||||
|   } |   } | ||||||
|   copy->h_addr_list[i] = NULL; |   copy->h_addr_list[i] = NULL; | ||||||
|  |  | ||||||
|  |   *buf=(char *)realloc(*buf, (int)bufptr-(int)(*buf)); | ||||||
|   return copy; |   return copy; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| @@ -405,14 +453,30 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len) | |||||||
|   return (addr); |   return (addr); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* 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. */ |  | ||||||
|  |  | ||||||
| #ifndef INADDR_NONE | #ifndef INADDR_NONE | ||||||
| #define INADDR_NONE (in_addr_t) ~0 | #define INADDR_NONE (in_addr_t) ~0 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | static void hostcache_fixoffset(struct hostent *h, int offset) | ||||||
|  | { | ||||||
|  |   int i=0; | ||||||
|  |   h->h_name=(char *)((int)h->h_name+offset); | ||||||
|  |   h->h_aliases=(char **)((int)h->h_aliases+offset); | ||||||
|  |   while(h->h_aliases[i]) { | ||||||
|  |     h->h_aliases[i]=(char *)((int)h->h_aliases[i]+offset); | ||||||
|  |     i++; | ||||||
|  |   } | ||||||
|  |   h->h_addr_list=(char **)((int)h->h_addr_list+offset); | ||||||
|  |   i=0; | ||||||
|  |   while(h->h_addr_list[i]) { | ||||||
|  |     h->h_addr_list[i]=(char *)((int)h->h_addr_list[i]+offset); | ||||||
|  |     i++; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* 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. */ | ||||||
| Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||||
|                                 char *hostname, |                                 char *hostname, | ||||||
|                                 int port, |                                 int port, | ||||||
| @@ -427,16 +491,15 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
|    * everything. OSF1 is known to require at least 8872 bytes. The buffer |    * everything. OSF1 is known to require at least 8872 bytes. The buffer | ||||||
|    * required for storing all possible aliases and IP numbers is according to |    * required for storing all possible aliases and IP numbers is according to | ||||||
|    * Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */ |    * Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */ | ||||||
|   int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE); |  | ||||||
|   if(!buf) |  | ||||||
|     return NULL; /* major failure */ |  | ||||||
|   *bufp = (char *)buf; |  | ||||||
|  |  | ||||||
|   port=0; /* unused in IPv4 code */ |   port=0; /* unused in IPv4 code */ | ||||||
|   ret = 0; /* to prevent the compiler warning */ |   ret = 0; /* to prevent the compiler warning */ | ||||||
|  |  | ||||||
|   if ( (in=inet_addr(hostname)) != INADDR_NONE ) { |   if ( (in=inet_addr(hostname)) != INADDR_NONE ) { | ||||||
|     struct in_addr *addrentry; |     struct in_addr *addrentry; | ||||||
|  |     int *buf = (int *)malloc(128); | ||||||
|  |     if(!buf) | ||||||
|  |       return NULL; /* major failure */ | ||||||
|  |     *bufp = (char *)buf; | ||||||
|  |  | ||||||
|     h = (struct hostent*)buf; |     h = (struct hostent*)buf; | ||||||
|     h->h_addr_list = (char**)(buf + sizeof(*h)); |     h->h_addr_list = (char**)(buf + sizeof(*h)); | ||||||
| @@ -448,30 +511,78 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
|     h->h_length = sizeof(*addrentry); |     h->h_length = sizeof(*addrentry); | ||||||
|     h->h_name = *(h->h_addr_list) + h->h_length; |     h->h_name = *(h->h_addr_list) + h->h_length; | ||||||
|     /* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */ |     /* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */ | ||||||
|     MakeIP(ntohl(in),h->h_name, CURL_NAMELOOKUP_SIZE - (long)(h->h_name) + (long)buf); |     MakeIP(ntohl(in),h->h_name, 128 - (long)(h->h_name) + (long)buf); | ||||||
|   } |   } | ||||||
| #if defined(HAVE_GETHOSTBYNAME_R) | #if defined(HAVE_GETHOSTBYNAME_R) | ||||||
|   else { |   else { | ||||||
|     int h_errnop; |     int h_errnop; | ||||||
|  |     int res=ERANGE; | ||||||
|  |     int step_size=200; | ||||||
|  |     int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE); | ||||||
|  |     if(!buf) | ||||||
|  |       return NULL; /* major failure */ | ||||||
|  |     *bufp=(char *)buf; | ||||||
|  |  | ||||||
|      /* Workaround for gethostbyname_r bug in qnx nto. It is also _required_ |      /* Workaround for gethostbyname_r bug in qnx nto. It is also _required_ | ||||||
|         for some of these functions. */ |         for some of these functions. */ | ||||||
|     memset(buf, 0, CURL_NAMELOOKUP_SIZE); |     memset(buf, 0, CURL_NAMELOOKUP_SIZE); | ||||||
| #ifdef HAVE_GETHOSTBYNAME_R_5 | #ifdef HAVE_GETHOSTBYNAME_R_5 | ||||||
|     /* Solaris, IRIX and more */ |     /* Solaris, IRIX and more */ | ||||||
|     if ((h = gethostbyname_r(hostname, |     while(!h) { | ||||||
|                              (struct hostent *)buf, |       h = gethostbyname_r(hostname, | ||||||
|                              (char *)buf + sizeof(struct hostent), |                           (struct hostent *)buf, | ||||||
|                              CURL_NAMELOOKUP_SIZE - sizeof(struct hostent), |                           (char *)buf + sizeof(struct hostent), | ||||||
|                              &h_errnop)) == NULL ) |                           step_size - sizeof(struct hostent), | ||||||
|  |                           &h_errnop); | ||||||
|  |  | ||||||
|  |       /* If the buffer is too small, it returns NULL and sets errno to | ||||||
|  |          ERANGE. The errno is thread safe if this is compiled with | ||||||
|  |          -D_REENTRANT as then the 'errno' variable is a macro defined to | ||||||
|  |          get used properly for threads. */ | ||||||
|  |  | ||||||
|  |       if(h || (errno != ERANGE)) | ||||||
|  |         break; | ||||||
|  |        | ||||||
|  |       step_size+=200; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #ifdef MALLOCDEBUG | ||||||
|  |     infof(data, "gethostbyname_r() uses %d bytes\n", step_size); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     if(h) { | ||||||
|  |       int offset; | ||||||
|  |       h=(struct hostent *)realloc(buf, step_size); | ||||||
|  |       offset=(int)h-(int)buf; | ||||||
|  |       hostcache_fixoffset(h, offset); | ||||||
|  |       buf=(int *)h; | ||||||
|  |       *bufp=(char *)buf; | ||||||
|  |     } | ||||||
|  |     else | ||||||
| #endif | #endif | ||||||
| #ifdef HAVE_GETHOSTBYNAME_R_6 | #ifdef HAVE_GETHOSTBYNAME_R_6 | ||||||
|     /* Linux */ |     /* Linux */ | ||||||
|     if( gethostbyname_r(hostname, |     while((res=gethostbyname_r(hostname, | ||||||
|                         (struct hostent *)buf, |                                (struct hostent *)buf, | ||||||
|                         (char *)buf + sizeof(struct hostent), |                                (char *)buf + sizeof(struct hostent), | ||||||
|                         CURL_NAMELOOKUP_SIZE - sizeof(struct hostent), |                                step_size - sizeof(struct hostent), | ||||||
|                         &h, /* DIFFERENCE */ |                                &h, /* DIFFERENCE */ | ||||||
|                         &h_errnop)) |                                &h_errnop))==ERANGE) { | ||||||
|  |       step_size+=200; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | #ifdef MALLOCDEBUG | ||||||
|  |     infof(data, "gethostbyname_r() uses %d bytes\n", step_size); | ||||||
|  | #endif | ||||||
|  |     if(!res) { | ||||||
|  |       int offset; | ||||||
|  |       h=(struct hostent *)realloc(buf, step_size); | ||||||
|  |       offset=(int)h-(int)buf; | ||||||
|  |       hostcache_fixoffset(h, offset); | ||||||
|  |       buf=(int *)h; | ||||||
|  |       *bufp=(char *)buf; | ||||||
|  |     } | ||||||
|  |     else | ||||||
| #endif | #endif | ||||||
| #ifdef HAVE_GETHOSTBYNAME_R_3 | #ifdef HAVE_GETHOSTBYNAME_R_3 | ||||||
|     /* AIX, Digital Unix, HPUX 10, more? */ |     /* AIX, Digital Unix, HPUX 10, more? */ | ||||||
| @@ -484,8 +595,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
|        * size dilemma. */ |        * size dilemma. */ | ||||||
|  |  | ||||||
|       ret = gethostbyname_r(hostname, |       ret = gethostbyname_r(hostname, | ||||||
|                           (struct hostent *)buf, |                             (struct hostent *)buf, | ||||||
|                           (struct hostent_data *)(buf + sizeof(struct hostent))); |                             (struct hostent_data *)(buf + sizeof(struct hostent))); | ||||||
|     else |     else | ||||||
|       ret = -1; /* failure, too smallish buffer size */ |       ret = -1; /* failure, too smallish buffer size */ | ||||||
|      |      | ||||||
| @@ -504,14 +615,17 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | |||||||
|   else { |   else { | ||||||
|     if ((h = gethostbyname(hostname)) == NULL ) { |     if ((h = gethostbyname(hostname)) == NULL ) { | ||||||
|       infof(data, "gethostbyname(2) failed for %s\n", hostname); |       infof(data, "gethostbyname(2) failed for %s\n", hostname); | ||||||
|       free(buf); |  | ||||||
|       *bufp=NULL; |       *bufp=NULL; | ||||||
|     } |     } | ||||||
|     else  |     else  | ||||||
|  |     { | ||||||
|  |       char *buf=(char *)malloc(CURL_NAMELOOKUP_SIZE); | ||||||
|       /* we make a copy of the hostent right now, right here, as the |       /* we make a copy of the hostent right now, right here, as the | ||||||
|          static one we got a pointer to might get removed when we don't |          static one we got a pointer to might get removed when we don't | ||||||
|          want/expect that */ |          want/expect that */ | ||||||
|       h = pack_hostent((char *)buf, h); |       h = pack_hostent(&buf, h); | ||||||
|  |       *bufp=(char *)buf; | ||||||
|  |     } | ||||||
| #endif | #endif | ||||||
|   } |   } | ||||||
|   return (h); |   return (h); | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -37,8 +37,7 @@ curl_hash *Curl_global_host_cache_get(void); | |||||||
|  |  | ||||||
| Curl_addrinfo *Curl_resolv(struct SessionHandle *data, | Curl_addrinfo *Curl_resolv(struct SessionHandle *data, | ||||||
| 			   char *hostname, | 			   char *hostname, | ||||||
| 			   int port, | 			   int port); | ||||||
| 			   char **bufp); |  | ||||||
|  |  | ||||||
| /* Get name info */ | /* Get name info */ | ||||||
| Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, | ||||||
|   | |||||||
							
								
								
									
										121
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								lib/http.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  *                            | (__| |_| |  _ <| |___  |  *                            | (__| |_| |  _ <| |___  | ||||||
|  *                             \___|\___/|_| \_\_____| |  *                             \___|\___/|_| \_\_____| | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. |  * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
|  * |  * | ||||||
|  * In order to be useful for every potential user, curl and libcurl are |  * In order to be useful for every potential user, curl and libcurl are | ||||||
|  * dual-licensed under the MPL and the MIT/X-derivate licenses. |  * dual-licensed under the MPL and the MIT/X-derivate licenses. | ||||||
| @@ -133,12 +133,6 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in, | |||||||
|   char *ptr; |   char *ptr; | ||||||
|   int size; |   int size; | ||||||
|  |  | ||||||
|   if(conn->data->set.verbose) { |  | ||||||
|     fputs("> ", conn->data->set.err); |  | ||||||
|     /* this data _may_ contain binary stuff */ |  | ||||||
|     fwrite(in->buffer, in->size_used, 1, conn->data->set.err); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* The looping below is required since we use non-blocking sockets, but due |   /* The looping below is required since we use non-blocking sockets, but due | ||||||
|      to the circumstances we will just loop and try again and again etc */ |      to the circumstances we will just loop and try again and again etc */ | ||||||
|  |  | ||||||
| @@ -150,6 +144,10 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in, | |||||||
|     if(CURLE_OK != res) |     if(CURLE_OK != res) | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|  |     if(conn->data->set.verbose) | ||||||
|  |       /* this data _may_ contain binary stuff */ | ||||||
|  |       Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount); | ||||||
|  |  | ||||||
|     if(amount != size) { |     if(amount != size) { | ||||||
|       size -= amount; |       size -= amount; | ||||||
|       ptr += amount; |       ptr += amount; | ||||||
| @@ -364,11 +362,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | |||||||
|                the line isn't really terminated until the LF comes */ |                the line isn't really terminated until the LF comes */ | ||||||
|  |  | ||||||
|             /* output debug output if that is requested */ |             /* output debug output if that is requested */ | ||||||
|             if(data->set.verbose) { |             if(data->set.verbose) | ||||||
|               fputs("< ", data->set.err); |               Curl_debug(data, CURLINFO_DATA_IN, line_start, perline); | ||||||
|               fwrite(line_start, perline, 1, data->set.err); |  | ||||||
|               /* no need to output LF here, it is part of the data */ |  | ||||||
|             } |  | ||||||
|              |              | ||||||
|             if('\r' == line_start[0]) { |             if('\r' == line_start[0]) { | ||||||
|               /* end of headers */ |               /* end of headers */ | ||||||
| @@ -392,7 +387,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | |||||||
|   } /* while there's buffer left and loop is requested */ |   } /* while there's buffer left and loop is requested */ | ||||||
|  |  | ||||||
|   if(error) |   if(error) | ||||||
|     return CURLE_READ_ERROR; |     return CURLE_RECV_ERROR; | ||||||
|  |  | ||||||
|   if(200 != httperror) { |   if(200 != httperror) { | ||||||
|     if(407 == httperror) |     if(407 == httperror) | ||||||
| @@ -400,7 +395,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, | |||||||
|       failf(data, "Proxy requires authorization!"); |       failf(data, "Proxy requires authorization!"); | ||||||
|     else  |     else  | ||||||
|       failf(data, "Received error code %d from proxy", httperror); |       failf(data, "Received error code %d from proxy", httperror); | ||||||
|     return CURLE_READ_ERROR; |     return CURLE_RECV_ERROR; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   infof (data, "Proxy replied to CONNECT request\n"); |   infof (data, "Proxy replied to CONNECT request\n"); | ||||||
| @@ -567,7 +562,13 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|   if(HTTPREQ_POST_FORM == data->set.httpreq) { |   if(HTTPREQ_POST_FORM == data->set.httpreq) { | ||||||
|     /* we must build the whole darned post sequence first, so that we have |     /* we must build the whole darned post sequence first, so that we have | ||||||
|        a size of the whole shebang before we start to send it */ |        a size of the whole shebang before we start to send it */ | ||||||
|     http->sendit = Curl_getFormData(data->set.httppost, &http->postsize); |      result = Curl_getFormData(&http->sendit, data->set.httppost, | ||||||
|  |                                &http->postsize); | ||||||
|  |      if(CURLE_OK != result) { | ||||||
|  |        /* Curl_getFormData() doesn't use failf() */ | ||||||
|  |        failf(data, "failed creating formpost data"); | ||||||
|  |        return result; | ||||||
|  |      } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if(!checkheaders(data, "Host:")) { |   if(!checkheaders(data, "Host:")) { | ||||||
| @@ -780,16 +781,16 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|       strcpy(buf, "no strftime() support"); |       strcpy(buf, "no strftime() support"); | ||||||
| #endif | #endif | ||||||
|       switch(data->set.timecondition) { |       switch(data->set.timecondition) { | ||||||
|       case TIMECOND_IFMODSINCE: |       case CURL_TIMECOND_IFMODSINCE: | ||||||
|       default: |       default: | ||||||
|         add_bufferf(req_buffer, |         add_bufferf(req_buffer, | ||||||
|                     "If-Modified-Since: %s\r\n", buf); |                     "If-Modified-Since: %s\r\n", buf); | ||||||
|         break; |         break; | ||||||
|       case TIMECOND_IFUNMODSINCE: |       case CURL_TIMECOND_IFUNMODSINCE: | ||||||
|         add_bufferf(req_buffer, |         add_bufferf(req_buffer, | ||||||
|                     "If-Unmodified-Since: %s\r\n", buf); |                     "If-Unmodified-Since: %s\r\n", buf); | ||||||
|         break; |         break; | ||||||
|       case TIMECOND_LASTMOD: |       case CURL_TIMECOND_LASTMOD: | ||||||
|         add_bufferf(req_buffer, |         add_bufferf(req_buffer, | ||||||
|                     "Last-Modified: %s\r\n", buf); |                     "Last-Modified: %s\r\n", buf); | ||||||
|         break; |         break; | ||||||
| @@ -814,7 +815,9 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|       headers = headers->next; |       headers = headers->next; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if(HTTPREQ_POST_FORM == data->set.httpreq) { |     switch(data->set.httpreq) { | ||||||
|  |  | ||||||
|  |     case HTTPREQ_POST_FORM: | ||||||
|       if(Curl_FormInit(&http->form, http->sendit)) { |       if(Curl_FormInit(&http->form, http->sendit)) { | ||||||
|         failf(data, "Internal HTTP POST error!"); |         failf(data, "Internal HTTP POST error!"); | ||||||
|         return CURLE_HTTP_POST_ERROR; |         return CURLE_HTTP_POST_ERROR; | ||||||
| @@ -883,9 +886,9 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|         Curl_formclean(http->sendit); /* free that whole lot */ |         Curl_formclean(http->sendit); /* free that whole lot */ | ||||||
|         return result; |         return result; | ||||||
|       } |       } | ||||||
|     } |       break; | ||||||
|     else if(HTTPREQ_PUT == data->set.httpreq) { |  | ||||||
|       /* Let's PUT the data to the server! */ |     case HTTPREQ_PUT: /* Let's PUT the data to the server! */ | ||||||
|  |  | ||||||
|       if(data->set.infilesize>0) { |       if(data->set.infilesize>0) { | ||||||
|         add_bufferf(req_buffer, |         add_bufferf(req_buffer, | ||||||
| @@ -911,50 +914,50 @@ CURLcode Curl_http(struct connectdata *conn) | |||||||
|                                &http->writebytecount); |                                &http->writebytecount); | ||||||
|       if(result) |       if(result) | ||||||
|         return result; |         return result; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|     } |     case HTTPREQ_POST: | ||||||
|     else { |       /* this is the simple POST, using x-www-form-urlencoded style */ | ||||||
|       if(HTTPREQ_POST == data->set.httpreq) { |  | ||||||
|         /* this is the simple POST, using x-www-form-urlencoded style */ |  | ||||||
|  |  | ||||||
|         if(!data->set.postfields) { |       if(!checkheaders(data, "Content-Length:")) | ||||||
|           /* |         /* we allow replacing this header, although it isn't very wise to | ||||||
|            * This is an attempt to do a POST without having anything to |            actually set your own */ | ||||||
|            * actually send. Let's make a NULL pointer equal "" here. Good/bad |         add_bufferf(req_buffer, | ||||||
|            * ? |                     "Content-Length: %d\r\n", | ||||||
|            */ |                     (data->set.postfieldsize?data->set.postfieldsize: | ||||||
|           data->set.postfields = (char *)""; |                      strlen(data->set.postfields)) ); | ||||||
|           data->set.postfieldsize = 0; /* it might been set to something illegal, |  | ||||||
|                                       anything > 0 would be! */ |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if(!checkheaders(data, "Content-Length:")) |       if(!checkheaders(data, "Content-Type:")) | ||||||
|           /* we allow replacing this header, although it isn't very wise to |         add_bufferf(req_buffer, | ||||||
|              actually set your own */ |                     "Content-Type: application/x-www-form-urlencoded\r\n"); | ||||||
|           add_bufferf(req_buffer, |  | ||||||
|                       "Content-Length: %d\r\n", |  | ||||||
|                       (data->set.postfieldsize?data->set.postfieldsize: |  | ||||||
|                        strlen(data->set.postfields)) ); |  | ||||||
|  |  | ||||||
|         if(!checkheaders(data, "Content-Type:")) |       add_buffer(req_buffer, "\r\n", 2); | ||||||
|           add_bufferf(req_buffer, |  | ||||||
|                       "Content-Type: application/x-www-form-urlencoded\r\n"); |  | ||||||
|  |  | ||||||
|         /* and here comes the actual data */ |       /* and here comes the actual data */ | ||||||
|         if(data->set.postfieldsize) { |       if(data->set.postfieldsize && data->set.postfields) { | ||||||
|           add_buffer(req_buffer, "\r\n", 2); |         add_buffer(req_buffer, data->set.postfields, | ||||||
|           add_buffer(req_buffer, data->set.postfields, |                    data->set.postfieldsize); | ||||||
|                      data->set.postfieldsize); |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|           add_bufferf(req_buffer, |  | ||||||
|                       "\r\n" |  | ||||||
|                       "%s", |  | ||||||
|                       data->set.postfields ); |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|  |       else if(data->set.postfields) | ||||||
|  |         add_bufferf(req_buffer, | ||||||
|  |                     "%s", | ||||||
|  |                     data->set.postfields ); | ||||||
|  |  | ||||||
|  |       /* issue the request */ | ||||||
|  |       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||||
|  |                                &data->info.request_size); | ||||||
|  |  | ||||||
|  |       if(result) | ||||||
|  |         failf(data, "Failed sending HTTP POST request"); | ||||||
|       else |       else | ||||||
|         add_buffer(req_buffer, "\r\n", 2); |         result = | ||||||
|  |           Curl_Transfer(conn, conn->firstsocket, -1, TRUE, bytecount, | ||||||
|  |                         data->set.postfields?-1:conn->firstsocket, | ||||||
|  |                         data->set.postfields?NULL:&http->writebytecount); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     default: | ||||||
|  |       add_buffer(req_buffer, "\r\n", 2); | ||||||
|        |        | ||||||
|       /* issue the request */ |       /* issue the request */ | ||||||
|       result = add_buffer_send(conn->firstsocket, conn, req_buffer, |       result = add_buffer_send(conn->firstsocket, conn, req_buffer, | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user