Compare commits
	
		
			419 Commits
		
	
	
		
			curl-7_22_
			...
			curl-7_24_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a8e063b087 | ||
|   | 70f71bb99f | ||
|   | c11c30a8c8 | ||
|   | 75ca568fa1 | ||
|   | db1a856b4f | ||
|   | ee57e9dea6 | ||
|   | 6e2fd2c9ea | ||
|   | 5d7a319a55 | ||
|   | 7883cd5af3 | ||
|   | d7af7de5b2 | ||
|   | a7e8f4aabc | ||
|   | e64d332e79 | ||
|   | 00e615de7e | ||
|   | b2aaf3c2ad | ||
|   | c41f304c43 | ||
|   | d56b4c3f89 | ||
|   | d1becc3231 | ||
|   | f55f95d49c | ||
|   | 61d31a3caf | ||
|   | 4b9af77d54 | ||
|   | 5d70a61b94 | ||
|   | 51c485342b | ||
|   | 4563eeb9f4 | ||
|   | 2cafb0e97c | ||
|   | 6ea7acf5a9 | ||
|   | a20daf90e3 | ||
|   | 24526d0c0f | ||
|   | a752850acc | ||
|   | 2b9fafd622 | ||
|   | 0ce2bca741 | ||
|   | b15024be4d | ||
|   | 21401840fa | ||
|   | e3e24e5b36 | ||
|   | 18c6c8a5e7 | ||
|   | c731fc58ea | ||
|   | 6d62c5a6fc | ||
|   | f1092b387e | ||
|   | 8e82ef9c32 | ||
|   | d016f5f5f5 | ||
|   | d4bf87dc0e | ||
|   | 54dede4166 | ||
|   | 9f20379fe4 | ||
|   | 123c92c904 | ||
|   | d28411c3cc | ||
|   | 2705af6267 | ||
|   | f34ddb90e6 | ||
|   | dd69a3e868 | ||
|   | 812fa73057 | ||
|   | 52824ed1ab | ||
|   | 4897f4e517 | ||
|   | 81524cbfa0 | ||
|   | 8ef7a5706e | ||
|   | c358bab809 | ||
|   | 4bc6c1a026 | ||
|   | 3a55daee3d | ||
|   | 7bd2add06f | ||
|   | 3b06f1fb36 | ||
|   | db4f69ef06 | ||
|   | 277022b2e4 | ||
|   | 0f8239d5b4 | ||
|   | a4202be655 | ||
|   | 2f4a487a68 | ||
|   | 82180643f4 | ||
|   | 585b89a6c3 | ||
|   | cc69e56ce3 | ||
|   | 8e25d1b93b | ||
|   | 63e2718f8d | ||
|   | 7f472618de | ||
|   | 08107111ac | ||
|   | a3403db02f | ||
|   | c9a3cab6c4 | ||
|   | f4949e56eb | ||
|   | 81ebdd9e28 | ||
|   | 207cf15032 | ||
|   | 5e0a44e4d5 | ||
|   | 9e3f8c4850 | ||
|   | 90343c76c6 | ||
|   | ecd75e8cb8 | ||
|   | e63c9f8ff3 | ||
|   | ed0364343d | ||
|   | 5c0ad9581d | ||
|   | e99128a5c9 | ||
|   | 33c2e1cafc | ||
|   | 84f736981c | ||
|   | 82c344a347 | ||
|   | 9f7f6a62ff | ||
|   | 98292bcdd0 | ||
|   | 996f2454ba | ||
|   | 99a12baa34 | ||
|   | 4f8db8bf95 | ||
|   | 5ac9ec7205 | ||
|   | f8cd217f04 | ||
|   | 84e7ea2ffc | ||
|   | 2caa454dc1 | ||
|   | 3e4181f88e | ||
|   | e71e226f6b | ||
|   | b0eb963bc7 | ||
|   | 2cf9e78a22 | ||
|   | 430527a1d7 | ||
|   | 1afbccc676 | ||
|   | 1dd654644a | ||
|   | ba238e3a18 | ||
|   | 4bb140bfc9 | ||
|   | 926916e28e | ||
|   | 3d6e2ec925 | ||
|   | 380bade777 | ||
|   | 26ce3ac328 | ||
|   | 130fac6c16 | ||
|   | 6222ef8052 | ||
|   | b06ed249d2 | ||
|   | 377471f387 | ||
|   | dfdac61522 | ||
|   | c834213ad5 | ||
|   | 5527417afa | ||
|   | bedfafe38e | ||
|   | e9040f2954 | ||
|   | 51d4885ca0 | ||
|   | ce896875f8 | ||
|   | eb6e9593c4 | ||
|   | 5c71544fc6 | ||
|   | 7799ac434e | ||
|   | 7cc2e8b349 | ||
|   | 3c18b38dcc | ||
|   | 1fc5cd6a1a | ||
|   | af9bc1604c | ||
|   | b235d5ade8 | ||
|   | ee3d3adc6f | ||
|   | 583a902789 | ||
|   | 7b8590d1f5 | ||
|   | 9b185aac43 | ||
|   | 34f9ec0c54 | ||
|   | 7111ca6f5f | ||
|   | 612a61b267 | ||
|   | cd4cd66839 | ||
|   | 4c4e8ba1f0 | ||
|   | de6f4f356e | ||
|   | 66c5076252 | ||
|   | b9b772fefe | ||
|   | 07efe110cc | ||
|   | 6e4835c795 | ||
|   | ba057c2e19 | ||
|   | 1259ccf747 | ||
|   | 07e3b7512c | ||
|   | 50d88bf4b5 | ||
|   | 1cacf853da | ||
|   | 9dbe6565d4 | ||
|   | 2b24dd870e | ||
|   | 46724b87b7 | ||
|   | 82a4d26e7f | ||
|   | 2b0e09b0f9 | ||
|   | 361cd03d58 | ||
|   | 7e4daaf908 | ||
|   | 3bbe219be2 | ||
|   | 347f951c39 | ||
|   | c50dbf670f | ||
|   | 0cf05af744 | ||
|   | d5b5f64bce | ||
|   | 088ba97a24 | ||
|   | 9109cdec11 | ||
|   | 5971d401d4 | ||
|   | 62d3652b43 | ||
|   | d81f5ea3e0 | ||
|   | adc88ca203 | ||
|   | 83350c9cc4 | ||
|   | bdb647814e | ||
|   | c92234c3bc | ||
|   | 7e02f7fdee | ||
|   | bd94807003 | ||
|   | 1038d0aa16 | ||
|   | f80a508297 | ||
|   | af64666434 | ||
|   | 2d72489f0f | ||
|   | dda815b776 | ||
|   | 8d3efb6be0 | ||
|   | 11e52ef0a1 | ||
|   | 71ce2470dc | ||
|   | 874855b743 | ||
|   | ac54d27d4b | ||
|   | 2d833852f6 | ||
|   | 0604b2fb90 | ||
|   | 8f50a5c7e5 | ||
|   | 703fa0a6a8 | ||
|   | 97d7a9260e | ||
|   | 4a4d04446d | ||
|   | b9223a17b8 | ||
|   | f712ace9d7 | ||
|   | 2c905fd1f8 | ||
|   | 4403e82f32 | ||
|   | c482e946f7 | ||
|   | 46bd8b330a | ||
|   | 78feaff9d8 | ||
|   | 28bac99674 | ||
|   | 7248439fec | ||
|   | c532604b13 | ||
|   | 64f328c787 | ||
|   | c0db5ff678 | ||
|   | 66617b79d7 | ||
|   | f64812ca63 | ||
|   | 10ecdf5078 | ||
|   | bb4eb58996 | ||
|   | fc8809f993 | ||
|   | 35f61c404d | ||
|   | 97b73fec7a | ||
|   | 8d0a504f0d | ||
|   | 967b2f87a8 | ||
|   | b9660dc4b2 | ||
|   | 591c29aa49 | ||
|   | 5e0aa3aac9 | ||
|   | 7cfd10e255 | ||
|   | 95ddbdb1db | ||
|   | 6c4216b2a7 | ||
|   | 10120e6ab5 | ||
|   | 082e8a3b03 | ||
|   | fd765c627f | ||
|   | c8ffb4049a | ||
|   | e3166df1bb | ||
|   | 06a83e8050 | ||
|   | 2c09d21fdf | ||
|   | 4851dafcf1 | ||
|   | 73029dca5a | ||
|   | 5b57c54416 | ||
|   | 7fe9a50ab5 | ||
|   | 6fa6567b92 | ||
|   | 93e57d0628 | ||
|   | a873b95c21 | ||
|   | 6bdeca967d | ||
|   | 3f5e267b9d | ||
|   | f7dfe2b87a | ||
|   | af425efe83 | ||
|   | 9cfc0c73a7 | ||
|   | 49e3b2e03a | ||
|   | 8bfc3a800a | ||
|   | b24c28e6c2 | ||
|   | 0b315c1cf1 | ||
|   | e2928e1555 | ||
|   | f5bb370186 | ||
|   | bae4e3f035 | ||
|   | 3676ec9680 | ||
|   | 8ccf7bf8d7 | ||
|   | c761fcb055 | ||
|   | ddeab48245 | ||
|   | b0d42da26b | ||
|   | 120025b7f8 | ||
|   | 692f344118 | ||
|   | 51e5a2bf3f | ||
|   | 8165e05f29 | ||
|   | 4c88866737 | ||
|   | 4464583a6e | ||
|   | 22502c9550 | ||
|   | 39c6d18d9c | ||
|   | f4405d30e0 | ||
|   | e8d8843a02 | ||
|   | 134e87c53b | ||
|   | 515f11e79b | ||
|   | 5850cc4808 | ||
|   | c295565569 | ||
|   | e771344611 | ||
|   | a4471045bb | ||
|   | cc76bbe79b | ||
|   | d7934b8bd4 | ||
|   | d67b75c9f9 | ||
|   | 95d23d1ceb | ||
|   | a4758c3276 | ||
|   | 9d0d1ada05 | ||
|   | 629d2e3450 | ||
|   | 90fcad63cb | ||
|   | 1399c3da0d | ||
|   | ff0a295cdb | ||
|   | 4fa0166173 | ||
|   | adaa3f6e14 | ||
|   | cf0f6729e7 | ||
|   | 8036da870c | ||
|   | 2621dd42a4 | ||
|   | 2c8c46619b | ||
|   | ecbb08cea3 | ||
|   | 491c5a497c | ||
|   | 06e6755e87 | ||
|   | 052a08ff59 | ||
|   | f6980bbf24 | ||
|   | d47d95ac3b | ||
|   | b229c8ca8b | ||
|   | 337252bdd4 | ||
|   | 840eff44f2 | ||
|   | ff03ee2a3c | ||
|   | 62bcf005f4 | ||
|   | 1a416cd27a | ||
|   | 54ef47a5a0 | ||
|   | 8af94de50a | ||
|   | 1bab38780b | ||
|   | fd10c047df | ||
|   | ea12c72d12 | ||
|   | 47e4537ac6 | ||
|   | 03adff1eba | ||
|   | 34770b8ab0 | ||
|   | 880cf0bedc | ||
|   | bff78cc18e | ||
|   | 584dc8b8af | ||
|   | a84b8a3922 | ||
|   | acaf466401 | ||
|   | 71c9453393 | ||
|   | 17f48fe879 | ||
|   | b82bd05354 | ||
|   | 1958fe5745 | ||
|   | f7bfdbabf2 | ||
|   | 7afccf7a1e | ||
|   | 4a57bf6d10 | ||
|   | 7296b2aa25 | ||
|   | 6c849321d7 | ||
|   | 0f19e0145a | ||
|   | ec73fd89ed | ||
|   | 5bf0d74120 | ||
|   | fd87d9d2b9 | ||
|   | 0572ad6d01 | ||
|   | aa7d5b946a | ||
|   | 49b79b7631 | ||
|   | ca2c326361 | ||
|   | 5c809178c2 | ||
|   | fa77f54a03 | ||
|   | bc007d8ef5 | ||
|   | d0dbd1e98e | ||
|   | 4d327d20c6 | ||
|   | 185ed3409a | ||
|   | d54bcebad4 | ||
|   | 0435800f65 | ||
|   | 56ed07f7df | ||
|   | 381459fa65 | ||
|   | 15e3e45170 | ||
|   | 9dd85bced5 | ||
|   | 5d45285cf3 | ||
|   | 3d19e1eedf | ||
|   | 7be872c389 | ||
|   | 0c903ea189 | ||
|   | affed6725e | ||
|   | 7f304ab84f | ||
|   | e709cc8627 | ||
|   | db060304de | ||
|   | 5898a6a09b | ||
|   | 57fffa728b | ||
|   | 421a460278 | ||
|   | 5793bc370c | ||
|   | ff5ba6e43d | ||
|   | 9f2f8d5122 | ||
|   | bd158607ca | ||
|   | a2d4a98ddd | ||
|   | b4fccc1d8e | ||
|   | e2be8ceed9 | ||
|   | d439830621 | ||
|   | f4853db5e6 | ||
|   | d9f686db88 | ||
|   | a1087db5c6 | ||
|   | 400055bfaa | ||
|   | 5801ddb85c | ||
|   | 38b5744266 | ||
|   | bc28a35dbc | ||
|   | d2a47021c0 | ||
|   | 119f43360b | ||
|   | e276802ff8 | ||
|   | 2d6796aac5 | ||
|   | bb94b92894 | ||
|   | 230459dd00 | ||
|   | 745014b726 | ||
|   | b3ea4881a8 | ||
|   | c6702c7d3f | ||
|   | 8bab6700d9 | ||
|   | 081e289315 | ||
|   | 5f0764870f | ||
|   | 87a45c7998 | ||
|   | dafa2fc944 | ||
|   | ef3f1f3146 | ||
|   | ba52e0a93b | ||
|   | 40c27e299f | ||
|   | fa775b56de | ||
|   | fb3845a438 | ||
|   | 3c3aa09c65 | ||
|   | 01c172f5e8 | ||
|   | e9cf4cb791 | ||
|   | 322f3d5af7 | ||
|   | c1057fc9aa | ||
|   | 62b0fdca9e | ||
|   | 3317160c19 | ||
|   | 28526ed6e0 | ||
|   | e4172d934d | ||
|   | 977825a68c | ||
|   | a6b69b64ad | ||
|   | 9ecf53e154 | ||
|   | 84221006c9 | ||
|   | a6c168b893 | ||
|   | dee7a08f64 | ||
|   | cd3cf55b47 | ||
|   | 98a61d8e2e | ||
|   | 81b41095ef | ||
|   | 49c35a7f9f | ||
|   | 57119495da | ||
|   | fdecb56cbf | ||
|   | 00532341b5 | ||
|   | dae0b7d1aa | ||
|   | 42be24af89 | ||
|   | 260b0f4d0c | ||
|   | f50d4647d0 | ||
|   | 805b4740c7 | ||
|   | a75888f1d3 | ||
|   | b4b642eb45 | ||
|   | c0159d0edc | ||
|   | 93579cc363 | ||
|   | 4322d512ea | ||
|   | e4819ae1ef | ||
|   | 43c59765e1 | ||
|   | e533f59025 | ||
|   | e6697ef59c | ||
|   | ff9d858722 | ||
|   | f7583b2dea | ||
|   | 6b33873c57 | ||
|   | 90080da5fe | ||
|   | 0216e517d0 | ||
|   | aff70e2e95 | ||
|   | 6790a543d4 | ||
|   | 2411adb40b | ||
|   | d52cd3bd17 | ||
|   | b7e242de0e | 
| @@ -2,7 +2,7 @@ | ||||
| # | ||||
| # Place the curl source (including this makefile) into external/curl/ in the | ||||
| # Android source tree.  Then build them with 'make curl' or just 'make libcurl' | ||||
| # from the Android root. Tested with Android 1.5 and 2.1 | ||||
| # from the Android root. Tested with Android versions 1.5, 2.1-2.3 | ||||
| # | ||||
| # Note: you must first create a curl_config.h file by running configure in the | ||||
| # Android environment. The only way I've found to do this is tricky. Perform a | ||||
| @@ -42,7 +42,7 @@ | ||||
| # into the right place (but see the note about this below). | ||||
| # | ||||
| # Dan Fandrich | ||||
| # August 2010 | ||||
| # November 2011 | ||||
|  | ||||
| LOCAL_PATH:= $(call my-dir) | ||||
|  | ||||
|   | ||||
							
								
								
									
										0
									
								
								CMake/FindCARES.cmake
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								CMake/FindCARES.cmake
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @@ -36,7 +36,7 @@ winbuild/MakefileBuild.vc winbuild/Makefile.vc | ||||
| EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in	\ | ||||
|  curl-style.el sample.emacs RELEASE-NOTES buildconf 	\ | ||||
|  libcurl.pc.in vc6curl.dsw MacOSX-Framework Android.mk $(CMAKE_DIST)	\ | ||||
|  Makefile.msvc.names $(WINBUILD_DIST) | ||||
|  Makefile.msvc.names $(WINBUILD_DIST) lib/libcurl.vers.in | ||||
|  | ||||
| bin_SCRIPTS = curl-config | ||||
|  | ||||
|   | ||||
| @@ -73,10 +73,15 @@ mingw32: | ||||
| mingw32-clean: | ||||
| 	$(MAKE) -C lib -f Makefile.m32 clean | ||||
| 	$(MAKE) -C src -f Makefile.m32 clean | ||||
| 	$(MAKE) -C docs/examples -f Makefile.m32 clean | ||||
|  | ||||
| mingw32-vclean mingw32-distclean: | ||||
| 	$(MAKE) -C lib -f Makefile.m32 vclean | ||||
| 	$(MAKE) -C src -f Makefile.m32 vclean | ||||
| 	$(MAKE) -C docs/examples -f Makefile.m32 vclean | ||||
|  | ||||
| mingw32-examples%: | ||||
| 	$(MAKE) -C docs/examples -f Makefile.m32 CFG=$@ | ||||
|  | ||||
| mingw32%: | ||||
| 	$(MAKE) -C lib -f Makefile.m32 CFG=$@ | ||||
| @@ -217,34 +222,27 @@ netware: | ||||
| 	$(MAKE) -C lib -f Makefile.netware | ||||
| 	$(MAKE) -C src -f Makefile.netware | ||||
|  | ||||
| netware-ares: | ||||
| 	$(MAKE) -C lib -f Makefile.netware WITH_ARES=1 | ||||
| 	$(MAKE) -C src -f Makefile.netware WITH_ARES=1 | ||||
|  | ||||
| netware-ssl: | ||||
| 	$(MAKE) -C lib -f Makefile.netware WITH_SSL=1 | ||||
| 	$(MAKE) -C src -f Makefile.netware WITH_SSL=1 | ||||
|  | ||||
| netware-ssl-zlib: | ||||
| 	$(MAKE) -C lib -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1 | ||||
| 	$(MAKE) -C src -f Makefile.netware WITH_SSL=1 WITH_ZLIB=1 | ||||
|  | ||||
| netware-ssh2-ssl-zlib: | ||||
| 	$(MAKE) -C lib -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1 | ||||
| 	$(MAKE) -C src -f Makefile.netware WITH_SSH2=1 WITH_SSL=1 WITH_ZLIB=1 | ||||
|  | ||||
| netware-zlib: | ||||
| 	$(MAKE) -C lib -f Makefile.netware WITH_ZLIB=1 | ||||
| 	$(MAKE) -C src -f Makefile.netware WITH_ZLIB=1 | ||||
|  | ||||
| netware-clean: | ||||
| 	$(MAKE) -C lib -f Makefile.netware clean | ||||
| 	$(MAKE) -C src -f Makefile.netware clean | ||||
| 	$(MAKE) -C docs/examples -f Makefile.netware clean | ||||
|  | ||||
| netware-vclean netware-distclean: | ||||
| 	$(MAKE) -C lib -f Makefile.netware vclean | ||||
| 	$(MAKE) -C src -f Makefile.netware vclean | ||||
| 	$(MAKE) -C docs/examples -f Makefile.netware vclean | ||||
|  | ||||
| netware-install: | ||||
| 	$(MAKE) -C lib -f Makefile.netware install | ||||
| 	$(MAKE) -C src -f Makefile.netware install | ||||
|  | ||||
| netware-examples-%: | ||||
| 	$(MAKE) -C docs/examples -f Makefile.netware CFG=$@ | ||||
|  | ||||
| netware-%: | ||||
| 	$(MAKE) -C lib -f Makefile.netware CFG=$@ | ||||
| 	$(MAKE) -C src -f Makefile.netware CFG=$@ | ||||
|  | ||||
| unix: all | ||||
|  | ||||
| unix-ssl: ssl | ||||
|   | ||||
							
								
								
									
										176
									
								
								RELEASE-NOTES
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								RELEASE-NOTES
									
									
									
									
									
								
							| @@ -1,59 +1,84 @@ | ||||
| Curl and libcurl 7.22.0 | ||||
| Curl and libcurl 7.24.0 | ||||
|  | ||||
|  Public curl releases:         124 | ||||
|  Public curl releases:         127 | ||||
|  Command line options:         149 | ||||
|  curl_easy_setopt() options:   192 | ||||
|  Public functions in libcurl:  58 | ||||
|  Known libcurl bindings:       39 | ||||
|  Contributors:                 873 | ||||
|  Contributors:                 907 | ||||
|  | ||||
| This release includes the following security fixes: | ||||
|  | ||||
|  o curl was vulnerable to a data injection attack for certain protocols | ||||
|    http://curl.haxx.se/docs/adv_20120124.html | ||||
|  o curl was vulnerable to a SSL CBC IV vulnerability when built to use OpenSSL | ||||
|    http://curl.haxx.se/docs/adv_20120124B.html | ||||
|  | ||||
| This release includes the following changes: | ||||
|  | ||||
|  o Added CURLOPT_GSSAPI_DELEGATION | ||||
|  o Added support for NTLM delegation to Samba's winbind daemon helper ntlm_auth | ||||
|  o Display notes from setup file in testcurl.pl | ||||
|  o BSD-style lwIP TCP/IP stack experimental support on Windows | ||||
|  o OpenSSL: Use SSL_MODE_RELEASE_BUFFERS if available | ||||
|  o --delegation was added to set CURLOPT_GSSAPI_DELEGATION | ||||
|  o nss: start with no database if the selected database is broken | ||||
|  o telnet: allow programatic use on Windows | ||||
|  o CURLOPT_QUOTE: SFTP supports the '*'-prefix now [24] | ||||
|  o CURLOPT_DNS_SERVERS: set name servers if possible [23] | ||||
|  o Add support for using nettle instead of gcrypt as gnutls backend [22] | ||||
|  o CURLOPT_INTERFACE: avoid resolving interfaces names with magic prefixes [21] | ||||
|  o Added CURLOPT_ACCEPTTIMEOUT_MS [30] | ||||
|  o configure: add symbols versioning option --enable-versioned-symbols [31] | ||||
|  | ||||
| This release includes the following bugfixes: | ||||
|  | ||||
|  o curl_getdate: detect some illegal dates better | ||||
|  o when sending a request and an error is received before the (entire) request | ||||
|    body is sent, stop sending the request and close the connection after | ||||
|    having received the entire response. This is equally true if an Expect: | ||||
|    100-continue header was used. | ||||
|  o When using both -J and a single -O with multiple URLs, a missing init | ||||
|    could cause a segfault | ||||
|  o -J fixed for escaped quotes | ||||
|  o -J fixed for file names with semicolons | ||||
|  o progress: reset flags at transfer start to avoid wrong  | ||||
|    CURLINFO_CONTENT_LENGTH_DOWNLOAD | ||||
|  o curl_gssapi: Guard files with HAVE_GSSAPI and rename private header | ||||
|  o silence picky compilers: mark unused parameters | ||||
|  o help output: more gnu like output | ||||
|  o libtests: stop checking for CURLM_CALL_MULTI_PERFORM | ||||
|  o setting a non-HTTP proxy with an environment variable or with CURLOPT_PROXY | ||||
|    / --proxy (without specifying CURLOPT_PROXYTYPE) would still make it do | ||||
|    proxy-like HTTP requests | ||||
|  o CURLFORM_BUFFER: insert filename as documented (regression) | ||||
|  o SOCKS: fix the connect timeout | ||||
|  o ftp_doing: bail out on error properly while multi interfacing | ||||
|  o improved Content-Encoded decoding error message | ||||
|  o asyn-thread: check for dotted addresses before thread starts | ||||
|  o cmake: find winsock when building on windows | ||||
|  o Curl_retry_request: check return code | ||||
|  o cookies: handle 'secure=' as if it was 'secure' | ||||
|  o tests: break busy loops in tests 502, 555, and 573 | ||||
|  o FTP: fix proxy connect race condition with multi interface and SOCKS proxy | ||||
|  o RTSP: GET_PARAMETER requests have a body | ||||
|  o fixed several memory leaks in OOM situations | ||||
|  o bad expire(0) caused multi_socket API to hang | ||||
|  o Avoid ftruncate() static define with mingw64 | ||||
|  o mk-ca-bundle.pl: ignore untrusted certs | ||||
|  o builds with PolarSSL 1.0.0 | ||||
|  o SSL session share: move the age counter to the share object [1] | ||||
|  o -J -O: use -O name if no Content-Disposition header comes! [2] | ||||
|  o protocol_connect: show verbose connect and set connect time [3] | ||||
|  o query-part: ignore the URI part for given protocols [4] | ||||
|  o gnutls: only translate winsock errors for old versions [5] | ||||
|  o POP3: fix end of body detection [6] | ||||
|  o POP3: detect when LIST returns no mails | ||||
|  o TELNET: improved treatment of options [7] | ||||
|  o configure: add support for pkg-config detection of libidn [8] | ||||
|  o CyaSSL 2.0+ library initialization adjustment [9] | ||||
|  o multi interface: only use non-NULL socker function pointer | ||||
|  o call opensocket callback properly for active FTP | ||||
|  o don't call close socket callback for sockets created with accept() [10] | ||||
|  o differentiate better between host/proxy errors [11] | ||||
|  o SSH: fix CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 and --hostpubmd5 [12] | ||||
|  o multi: handle timeouts on DNS servers by checking for new sockets [13] | ||||
|  o CURLOPT_DNS_SERVERS: fix return code | ||||
|  o POP3: fixed escaped dot not being stripped out [14] | ||||
|  o OpenSSL: check for the SSLv2 function in configure [15] | ||||
|  o MakefileBuild: fix the static build [16] | ||||
|  o create_conn: don't switch to HTTP protocol if tunneling is enabled [17] | ||||
|  o multi interface: fix block when CONNECT_ONLY option is used [18] | ||||
|  o Fix connection reuse for TLS upgraded connections [19] | ||||
|  o multiple file upload with -F and custom type [20] | ||||
|  o multi interface: active FTP connections are no longer blocking [25] | ||||
|  o Android build fix [26] | ||||
|  o timer: restore PRETRANSFER timing [27] | ||||
|  o libcurl.m4: Fix quoting arguments of AC_LANG_PROGRAM [28] | ||||
|  o appconnect time fixed for non-blocking connect ssl backends [29] | ||||
|  o do not include SSL handshake into time spent waiting for 100-continue [32] | ||||
|  o handle dns cache case insensitive | ||||
|  o use new host name casing for subsequent HTTP requests [33] | ||||
|  o CURLOPT_RESOLVE: avoid adding already present host names | ||||
|  o SFTP mkdir: use correct permission [34] | ||||
|  o resolve: don't leak pre-populated dns entries [35] | ||||
|  o --retry: Retry transfers on timeout and DNS errors | ||||
|  o negotiate with SSPI backend: use the correct buffer for input [36] | ||||
|  o SFTP dir: increase buffer size counter to avoid cut off file names [37] | ||||
|  o TFTP: fix resending (again) [38] | ||||
|  o c-ares: don't include getaddrinfo-using code [39] | ||||
|  o FTP: CURLE_PARTIAL_FILE will not close the control channel [40] | ||||
|  o win32-threaded-resolver: stop using a dummy socket | ||||
|  o OpenSSL: remove reference to openssl internal struct [41] | ||||
|  o OpenSSL: SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option no longer enabled | ||||
|  o OpenSSL: fix PKCS#12 certificate parsing related memory leak | ||||
|  o OpenLDAP: fix LDAP connection phase memory leak [42] | ||||
|  o Telnet: Use correct file descriptor for telnet upload | ||||
|  o Telnet: Remove bogus optimisation of telnet upload | ||||
|  o URL parse: user name with ipv6 numerical address | ||||
|  o polarssl: show cipher suite name correctly with 1.1.0 | ||||
|  o polarssl: havege_rand is not present in version 1.1.0 WARNING, we still | ||||
|    use the old API which is said to be insecure. See | ||||
|    http://polarssl.org/trac/wiki/SecurityAdvisory201102 | ||||
|  o gnutls: enforced use of SSLv3 [43] | ||||
|  | ||||
| This release includes the following known bugs: | ||||
|  | ||||
| @@ -62,11 +87,60 @@ This release includes the following known bugs: | ||||
| This release would not have looked like this without help, code, reports and | ||||
| advice from friends like these: | ||||
|  | ||||
|  Paolo Piacentini, Steven Parkes, Adam Tkac, Ben Winslow, Dan Fandrich, | ||||
|  Julien Chaffraix, Kamil Dudka, Mandy Wu, Michael Mueller, Patrick Monnerat, | ||||
|  Yang Tse, Paul Howarth, Garrett Holmstrom, Peter Hjalmarsson, Herve Amblard, | ||||
|  Christian Hagele, Richard Silverman, Henry Ludemann, Cristian Rodriguez, | ||||
|  Steve Holme, Jim Hollinger, Pau Garcia i Quiles, Fabian Keil, Wu Yongzheng, | ||||
|  Adriano Meirelles, Jeff Pohlmeyer | ||||
|  Alejandro Alvarez Ayllon, Jason Glasgow, Jonas Schnelli, Mark Brand, | ||||
|  Martin Storsjo, Yang Tse, Laurent Rabret, Jason Glasgow, Steve Holme, | ||||
|  Reza Arbab, Jason Liu, Gokhan Sengun, Rob Ward, Dan Fandrich, | ||||
|  Naveen Chandran, Ward Willats, Vladimir Grishchenko, Colin Hogben, | ||||
|  Alessandro Ghedini, Cedric Deltheil, Toni Moreno, Bernhard Reutner-Fischer, | ||||
|  Sven Wegener, Alex Vinnik, Kamil Dudka, Mamoru Tasaka, Patrice Guerin, | ||||
|  Armel Asselin, Arthur Murray, Steve H Truong, Peter Sylvester, | ||||
|  Johannes Bauer, Brandon Wang, Pierre Joye, Robert Schumann, | ||||
|  Christian Grothoff, Nikos Mavrogiannopoulos | ||||
|  | ||||
|         Thanks! (and sorry if I forgot to mention someone) | ||||
|  | ||||
| References to bug reports and discussions on issues: | ||||
|  | ||||
|  [1] = http://curl.haxx.se/mail/lib-2011-11/0116.html | ||||
|  [2] = http://curl.haxx.se/mail/archive-2011-11/0030.htm | ||||
|  [3] = http://curl.haxx.se/mail/archive-2011-11/0035.html | ||||
|  [4] = http://curl.haxx.se/mail/lib-2011-11/0218.html | ||||
|  [5] = http://curl.haxx.se/mail/lib-2011-11/0267.html | ||||
|  [6] = http://curl.haxx.se/mail/lib-2011-11/0279.html | ||||
|  [7] = http://curl.haxx.se/mail/lib-2011-11/0247.html | ||||
|  [8] = http://curl.haxx.se/mail/lib-2011-11/0294.html | ||||
|  [9] = http://curl.haxx.se/bug/view.cgi?id=3442068 | ||||
|  [10] = http://curl.haxx.se/mail/lib-2011-12/0018.html | ||||
|  [11] = http://curl.haxx.se/mail/archive-2011-12/0010.html | ||||
|  [12] = http://curl.haxx.se/bug/view.cgi?id=3451592 | ||||
|  [13] = http://curl.haxx.se/mail/lib-2011-11/0371.html | ||||
|  [14] = http://curl.haxx.se/mail/lib-2011-11/0368.html | ||||
|  [15] = http://curl.haxx.se/mail/archive-2011-12/0012.html | ||||
|  [16] = http://curl.haxx.se/mail/lib-2011-12/0063.html | ||||
|  [17] = http://curl.haxx.se/mail/lib-2011-12/0010.html | ||||
|  [18] = http://curl.haxx.se/mail/lib-2011-12/0070.html | ||||
|  [19] = http://curl.haxx.se/mail/lib-2011-11/0022.html | ||||
|  [20] = http://curl.haxx.se/mail/lib-2011-12/0121.html | ||||
|  [21] = http://curl.haxx.se/mail/lib-2011-12/0107.html | ||||
|  [22] = http://curl.haxx.se/mail/lib-2011-11/0164.html | ||||
|  [23] = http://curl.haxx.se/mail/lib-2011-11/0067.html | ||||
|  [24] = http://curl.haxx.se/mail/lib-2011-11/0205.html | ||||
|  [25] = http://curl.haxx.se/mail/lib-2011-12/0179.html | ||||
|  [26] = http://curl.haxx.se/mail/lib-2011-12/0215.html | ||||
|  [27] = http://curl.haxx.se/mail/archive-2011-12/0022.html | ||||
|  [28] = http://curl.haxx.se/mail/lib-2011-12/0218.html | ||||
|  [29] = http://curl.haxx.se/mail/lib-2011-12/0211.html | ||||
|  [30] = http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTACCEPTTIMOUTMS | ||||
|  [31] = http://curl.haxx.se/mail/lib-2011-12/0133.html | ||||
|  [32] = https://bugzilla.redhat.com/767490 | ||||
|  [33] = http://curl.haxx.se/mail/lib-2011-12/0314.html | ||||
|  [34] = http://curl.haxx.se/mail/lib-2011-12/0249.html | ||||
|  [35] = http://curl.haxx.se/bug/view.cgi?id=3463121 | ||||
|  [36] = http://curl.haxx.se/bug/view.cgi?id=3466497 | ||||
|  [37] = http://curl.haxx.se/mail/lib-2011-12/0249.html | ||||
|  [38] = http://curl.haxx.se/mail/lib-2012-01/0146.html | ||||
|  [39] = http://curl.haxx.se/mail/lib-2012-01/0160.html | ||||
|  [40] = http://curl.haxx.se/mail/lib-2012-01/0096.html | ||||
|  [41] = http://curl.haxx.se/mail/lib-2012-01/0049.html | ||||
|  [42] = http://curl.haxx.se/bug/view.cgi?id=3474308 | ||||
|  [43] = http://curl.haxx.se/mail/lib-2012-01/0225.html | ||||
|   | ||||
| @@ -51,7 +51,7 @@ CURL_DEF_TOKEN $1 | ||||
|   ],[ | ||||
|     tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \ | ||||
|       "$GREP" CURL_DEF_TOKEN 2>/dev/null | \ | ||||
|       "$SED" 's/.*CURL_DEF_TOKEN[[ ]]//' 2>/dev/null | \ | ||||
|       "$SED" 's/.*CURL_DEF_TOKEN[[ ]][[ ]]*//' 2>/dev/null | \ | ||||
|       "$SED" 's/[["]][[ ]]*[["]]//g' 2>/dev/null` | ||||
|     if test -z "$tmp_exp" || test "$tmp_exp" = "$1"; then | ||||
|       tmp_exp="" | ||||
|   | ||||
							
								
								
									
										166
									
								
								buildconf
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								buildconf
									
									
									
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
| #                            | (__| |_| |  _ <| |___ | ||||
| #                             \___|\___/|_| \_\_____| | ||||
| # | ||||
| # Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| # Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| # | ||||
| # This software is licensed as described in the file COPYING, which | ||||
| # you should have received as part of this distribution. The terms | ||||
| @@ -21,9 +21,12 @@ | ||||
| # | ||||
| ########################################################################### | ||||
|  | ||||
| #-------------------------------------------------------------------------- | ||||
| # die prints argument string to stdout and exits this shell script. | ||||
| # | ||||
| die(){ | ||||
| 	echo "$@" | ||||
| 	exit | ||||
|   echo "buildconf: $@" | ||||
|   exit 1 | ||||
| } | ||||
|  | ||||
| #-------------------------------------------------------------------------- | ||||
| @@ -33,11 +36,8 @@ die(){ | ||||
| findtool(){ | ||||
|   file="$1" | ||||
|  | ||||
|   if { echo $file | grep "/" >/dev/null 2>&1; } then | ||||
|     # we only check for the explicit file name if the file is given | ||||
|     # including a slash. Use ./ for current dir. Previously this would | ||||
|     # otherwise always cause findtool to search the local dir first, which | ||||
|     # is wrong. | ||||
|   if { echo "$file" | grep "/" >/dev/null 2>&1; } then | ||||
|     # when file is given with a path check it first | ||||
|     if test -f "$file"; then | ||||
|       echo "$file" | ||||
|       return | ||||
| @@ -80,16 +80,19 @@ removethis(){ | ||||
| # Ensure that buildconf runs from the subdirectory where configure.ac lives | ||||
| # | ||||
| if test ! -f configure.ac || | ||||
|   test ! -f src/main.c || | ||||
|   test ! -f src/tool_main.c || | ||||
|   test ! -f lib/urldata.h || | ||||
|   test ! -f include/curl/curl.h; then | ||||
|   test ! -f include/curl/curl.h || | ||||
|   test ! -f m4/curl-functions.m4; then | ||||
|   echo "Can not run buildconf from outside of curl's source subdirectory!" | ||||
|   echo "Change to the subdirectory where buildconf is found, and try again." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| #-------------------------------------------------------------------------- | ||||
| # autoconf 2.57 or newer | ||||
| # autoconf 2.57 or newer. Unpatched version 2.67 does not generate proper | ||||
| # configure script. Unpatched version 2.68 is simply unusable, we should | ||||
| # disallow 2.68 usage. | ||||
| # | ||||
| need_autoconf="2.57" | ||||
| ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'` | ||||
| @@ -108,7 +111,15 @@ if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| if test "$1" = "2" -a "$2" -eq "67"; then | ||||
|   echo "buildconf: autoconf version $ac_version (BAD)" | ||||
|   echo "            Unpatched version generates broken configure script." | ||||
| elif test "$1" = "2" -a "$2" -eq "68"; then | ||||
|   echo "buildconf: autoconf version $ac_version (BAD)" | ||||
|   echo "            Unpatched version generates unusable configure script." | ||||
| else | ||||
|   echo "buildconf: autoconf version $ac_version (ok)" | ||||
| fi | ||||
|  | ||||
| am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'` | ||||
| if test -z "$am4te_version"; then | ||||
| @@ -178,27 +189,24 @@ else | ||||
| fi | ||||
|  | ||||
| #-------------------------------------------------------------------------- | ||||
| # libtool check | ||||
| # GNU libtool preliminary check | ||||
| # | ||||
| LIBTOOL_WANTED_MAJOR=1 | ||||
| LIBTOOL_WANTED_MINOR=4 | ||||
| LIBTOOL_WANTED_PATCH=2 | ||||
| LIBTOOL_WANTED_VERSION=1.4.2 | ||||
| want_lt_major=1 | ||||
| want_lt_minor=4 | ||||
| want_lt_patch=2 | ||||
| want_lt_version=1.4.2 | ||||
|  | ||||
| # This approach that tries 'glibtool' first is intended for systems that | ||||
| # have GNU libtool named as 'glibtool' and libtool not being GNU's. | ||||
|  | ||||
| # this approach that tries 'glibtool' first is some kind of work-around for | ||||
| # some BSD-systems I believe that use to provide the GNU libtool named | ||||
| # glibtool, with 'libtool' being something completely different. | ||||
| libtool=`findtool glibtool 2>/dev/null` | ||||
| if test ! -x "$libtool"; then | ||||
|   libtool=`findtool ${LIBTOOL:-libtool}` | ||||
| fi | ||||
|  | ||||
| if test -z "$LIBTOOLIZE"; then | ||||
|   # set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found | ||||
|   # $libtool is already the full path | ||||
|   libtoolize="${libtool}ize" | ||||
| else | ||||
|   libtoolize=`findtool $LIBTOOLIZE` | ||||
| if test -z "$libtool"; then | ||||
|   echo "buildconf: libtool not found." | ||||
|   echo "            You need GNU libtool $want_lt_version or newer installed." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| lt_pver=`$libtool --version 2>/dev/null|head -n 1` | ||||
| @@ -206,42 +214,55 @@ lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"` | ||||
| lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"` | ||||
| if test -z "$lt_version"; then | ||||
|   echo "buildconf: libtool not found." | ||||
|   echo "            You need libtool version $LIBTOOL_WANTED_VERSION or newer installed" | ||||
|   echo "            You need GNU libtool $want_lt_version or newer installed." | ||||
|   exit 1 | ||||
| fi | ||||
| old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS | ||||
| lt_major=$1 | ||||
| lt_minor=$2 | ||||
| lt_patch=$3 | ||||
| lt_status="good" | ||||
|  | ||||
| if test "$lt_major" = "$LIBTOOL_WANTED_MAJOR"; then | ||||
|    if test "$lt_minor" -lt "$LIBTOOL_WANTED_MINOR"; then | ||||
| if test -z "$lt_major"; then | ||||
|   lt_status="bad" | ||||
|    elif test -n "$LIBTOOL_WANTED_PATCH"; then | ||||
|        if test "$lt_minor" -gt "$LIBTOOL_WANTED_MINOR"; then | ||||
| elif test "$lt_major" -gt "$want_lt_major"; then | ||||
|   lt_status="good" | ||||
|        elif test -n "$lt_patch"; then | ||||
|           if test "$lt_patch" -lt "$LIBTOOL_WANTED_PATCH"; then | ||||
| elif test "$lt_major" -lt "$want_lt_major"; then | ||||
|   lt_status="bad" | ||||
| elif test -z "$lt_minor"; then | ||||
|   lt_status="bad" | ||||
| elif test "$lt_minor" -gt "$want_lt_minor"; then | ||||
|   lt_status="good" | ||||
| elif test "$lt_minor" -lt "$want_lt_minor"; then | ||||
|   lt_status="bad" | ||||
| elif test -z "$lt_patch"; then | ||||
|   lt_status="bad" | ||||
| elif test "$lt_patch" -gt "$want_lt_patch"; then | ||||
|   lt_status="good" | ||||
| elif test "$lt_patch" -lt "$want_lt_patch"; then | ||||
|   lt_status="bad" | ||||
|           fi | ||||
| else | ||||
|           lt_status="bad" | ||||
|   lt_status="good" | ||||
| fi | ||||
|    fi | ||||
| fi | ||||
| if test $lt_status != "good"; then | ||||
| if test "$lt_status" != "good"; then | ||||
|   echo "buildconf: libtool version $lt_version found." | ||||
|   echo "            You need libtool version $LIBTOOL_WANTED_VERSION or newer installed" | ||||
|   echo "            You need GNU libtool $want_lt_version or newer installed." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| echo "buildconf: libtool version $lt_version (ok)" | ||||
|  | ||||
| if test -f "$libtoolize"; then | ||||
|   echo "buildconf: libtoolize found" | ||||
| #-------------------------------------------------------------------------- | ||||
| # GNU libtoolize check | ||||
| # | ||||
| if test -z "$LIBTOOLIZE"; then | ||||
|   # use (g)libtoolize from same location as (g)libtool | ||||
|   libtoolize="${libtool}ize" | ||||
| else | ||||
|   echo "buildconf: libtoolize not found. Weird libtool installation!" | ||||
|   libtoolize=`findtool $LIBTOOLIZE` | ||||
| fi | ||||
| if test ! -f "$libtoolize"; then | ||||
|   echo "buildconf: libtoolize not found." | ||||
|   echo "            You need GNU libtoolize $want_lt_version or newer installed." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| @@ -266,6 +287,10 @@ fi | ||||
| # perl check | ||||
| # | ||||
| PERL=`findtool ${PERL:-perl}` | ||||
| if test -z "$PERL"; then | ||||
|   echo "buildconf: perl not found" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| #-------------------------------------------------------------------------- | ||||
| # Remove files generated on previous buildconf/configure run. | ||||
| @@ -301,6 +326,7 @@ for fname in .deps \ | ||||
|     libcurl.pc \ | ||||
|     libtool \ | ||||
|     libtool.m4 \ | ||||
|     libtool.m4.tmp \ | ||||
|     ltmain.sh \ | ||||
|     ltoptions.m4 \ | ||||
|     ltsugar.m4 \ | ||||
| @@ -317,32 +343,52 @@ done | ||||
| # | ||||
|  | ||||
| echo "buildconf: running libtoolize" | ||||
| $libtoolize --copy --automake --force || die "The libtoolize command failed" | ||||
| ${libtoolize} --copy --automake --force || die "libtoolize command failed" | ||||
|  | ||||
| if test ! -f m4/curl-functions.m4; then | ||||
|   echo "buildconf: cURL m4 macros not found" | ||||
|   exit 1 | ||||
| # When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4 | ||||
| # subdirectory and this local copy is patched to fix some warnings that | ||||
| # are triggered when running aclocal and using autoconf 2.62 or later. | ||||
|  | ||||
| if test "$lt_major" = "1" && test "$lt_minor" = "5"; then | ||||
|   if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then | ||||
|     echo "buildconf: copying libtool.m4 to local m4 subdir" | ||||
|     ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir` | ||||
|     if test -f $ac_dir/libtool.m4; then | ||||
|       cp -f $ac_dir/libtool.m4 m4/libtool.m4 | ||||
|     else | ||||
|       echo "buildconf: $ac_dir/libtool.m4 not found" | ||||
|     fi | ||||
|     if test -f m4/libtool.m4; then | ||||
|       echo "buildconf: renaming some variables in local m4/libtool.m4" | ||||
|       $PERL -i.tmp -pe \ | ||||
|         's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \ | ||||
|          s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \ | ||||
|         m4/libtool.m4 | ||||
|       rm -f m4/libtool.m4.tmp | ||||
|     fi | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| if test -f m4/libtool.m4; then | ||||
|   echo "buildconf: converting all mv to mv -f in local m4/libtool.m4" | ||||
|   $PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4 | ||||
|   rm -f m4/libtool.m4.tmp | ||||
| fi | ||||
|  | ||||
| echo "buildconf: running aclocal" | ||||
| ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "The aclocal command line failed" | ||||
| ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed" | ||||
|  | ||||
| if test -n "$PERL"; then | ||||
|   echo "buildconf: running aclocal hack to convert all mv to mv -f" | ||||
| echo "buildconf: converting all mv to mv -f in local aclocal.m4" | ||||
| $PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 | ||||
| else | ||||
|   echo "buildconf: perl not found" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| echo "buildconf: running autoheader" | ||||
| ${AUTOHEADER:-autoheader} || die "The autoheader command failed" | ||||
| ${AUTOHEADER:-autoheader} || die "autoheader command failed" | ||||
|  | ||||
| echo "buildconf: cp lib/curl_config.h.in src/curl_config.h.in" | ||||
| cp lib/curl_config.h.in src/curl_config.h.in | ||||
|  | ||||
| echo "buildconf: running autoconf" | ||||
| ${AUTOCONF:-autoconf}     || die "The autoconf command failed" | ||||
| ${AUTOCONF:-autoconf} || die "autoconf command failed" | ||||
|  | ||||
| if test -d ares; then | ||||
|   cd ares | ||||
| @@ -352,14 +398,15 @@ if test -d ares; then | ||||
| fi | ||||
|  | ||||
| echo "buildconf: running automake" | ||||
| ${AUTOMAKE:-automake} -a -c  || die "The automake command failed" | ||||
| ${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed" | ||||
|  | ||||
| #-------------------------------------------------------------------------- | ||||
| # GNU libtool complementary check | ||||
| # | ||||
| # Depending on the libtool and automake versions being used, config.guess | ||||
| # might not be installed in the subdirectory until automake has finished. | ||||
| # So we can not attempt to use it until this very last buildconf stage. | ||||
| # | ||||
|  | ||||
| if test ! -f ./config.guess; then | ||||
|   echo "buildconf: config.guess not found" | ||||
| else | ||||
| @@ -403,7 +450,7 @@ else | ||||
|     if test "$lt_status" != "good"; then | ||||
|       need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch" | ||||
|       echo "buildconf: libtool version $lt_version found." | ||||
|       echo "            $buildhost requires libtool $need_lt_version or newer installed." | ||||
|       echo "            $buildhost requires GNU libtool $need_lt_version or newer installed." | ||||
|       rm -f configure | ||||
|       exit 1 | ||||
|     fi | ||||
| @@ -413,6 +460,5 @@ fi | ||||
| #-------------------------------------------------------------------------- | ||||
| # Finished successfully. | ||||
| # | ||||
|  | ||||
| echo "buildconf: OK" | ||||
| exit 0 | ||||
|   | ||||
							
								
								
									
										242
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										242
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -26,6 +26,7 @@ AC_PREREQ(2.57) | ||||
| dnl We don't know the version number "statically" so we use a dash here | ||||
| AC_INIT([curl], [-], [a suitable curl mailing list: http://curl.haxx.se/mail/]) | ||||
|  | ||||
| XC_OVR_ZZ50 | ||||
| CURL_OVERRIDE_AUTOCONF | ||||
|  | ||||
| dnl configure script copyright | ||||
| @@ -1514,7 +1515,8 @@ if test X"$OPT_SSL" != Xno; then | ||||
|                     RAND_egd \ | ||||
|                     ENGINE_cleanup \ | ||||
|                     CRYPTO_cleanup_all_ex_data \ | ||||
|                     SSL_get_shutdown ) | ||||
|                     SSL_get_shutdown \ | ||||
|                     SSLv2_client_method ) | ||||
|  | ||||
|     dnl Make an attempt to detect if this is actually yassl's headers and | ||||
|     dnl OpenSSL emulation layer. We still leave everything else believing | ||||
| @@ -1799,17 +1801,30 @@ if test "$OPENSSL_ENABLED" != "1"; then | ||||
| fi dnl OPENSSL != 1 | ||||
|  | ||||
| dnl --- | ||||
| dnl If GnuTLS is enabled, we MUST verify that it uses libgcrypt since | ||||
| dnl curl code relies on that but recent GnuTLS versions can in fact build | ||||
| dnl with different crypto libraries which curl right now cannot handle | ||||
| dnl Check which crypto backend GnuTLS uses | ||||
| dnl --- | ||||
|  | ||||
| if test "$GNUTLS_ENABLED" = "1"; then | ||||
|   AC_CHECK_LIB(gcrypt, | ||||
|                gcry_control, , | ||||
|     [ | ||||
|       AC_MSG_ERROR([need GnuTLS built with gcrypt to function with GnuTLS]) | ||||
|     ]) | ||||
|   USE_GNUTLS_NETTLE= | ||||
|   # First check if we can detect either crypto library via transitive linking | ||||
|   AC_CHECK_LIB(gnutls, nettle_MD5Init, [ USE_GNUTLS_NETTLE=1 ]) | ||||
|   if test "$USE_GNUTLS_NETTLE" = ""; then | ||||
|     AC_CHECK_LIB(gnutls, gcry_control, [ USE_GNUTLS_NETTLE=0 ]) | ||||
|   fi | ||||
|   # If not, try linking directly to both of them to see if they are available | ||||
|   if test "$USE_GNUTLS_NETTLE" = ""; then | ||||
|     AC_CHECK_LIB(nettle, nettle_MD5Init, [ USE_GNUTLS_NETTLE=1 ]) | ||||
|   fi | ||||
|   if test "$USE_GNUTLS_NETTLE" = ""; then | ||||
|     AC_CHECK_LIB(gcrypt, gcry_control, [ USE_GNUTLS_NETTLE=0 ]) | ||||
|   fi | ||||
|   if test "$USE_GNUTLS_NETTLE" = ""; then | ||||
|     AC_MSG_ERROR([GnuTLS found, but neither gcrypt nor nettle found]) | ||||
|   fi | ||||
|   if test "$USE_GNUTLS_NETTLE" = "1"; then | ||||
|     AC_DEFINE(USE_GNUTLS_NETTLE, 1, [if GnuTLS uses nettle as crypto backend]) | ||||
|     AC_SUBST(USE_GNUTLS_NETTLE, [1]) | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| dnl --- | ||||
| @@ -2331,55 +2346,201 @@ if test X"$OPT_LIBRTMP" != Xno; then | ||||
|  | ||||
| fi | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Check for linker switch for versioned symbols | ||||
| dnl ********************************************************************** | ||||
|  | ||||
| AC_MSG_CHECKING([if libraries can be versioned]) | ||||
| GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script` | ||||
| if test -z "$GLD"; then | ||||
|     versioned_symbols_flavour= | ||||
|     AC_MSG_RESULT(no) | ||||
|     AC_MSG_WARN(*** | ||||
| *** You need an ld version supporting the --version-script option. | ||||
| ) | ||||
| else | ||||
|     AC_MSG_RESULT(yes) | ||||
|  | ||||
| AC_MSG_CHECKING([whether versioned symbols are wanted]) | ||||
| versioned_symbols_flavour= | ||||
|  | ||||
| AC_ARG_ENABLE(versioned-symbols, | ||||
| AC_HELP_STRING([--enable-versioned-symbols], [Enable versioned symbols in shared library]) | ||||
| AC_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shared library]), | ||||
| [ case "$enableval" in | ||||
|   yes) AC_MSG_RESULT(yes) | ||||
|     if test "x$OPENSSL_ENABLED" = "x1"; then | ||||
|       versioned_symbols_flavour="OPENSSL_" | ||||
|     elif test "x$GNUTLS_ENABLED" == "x1"; then | ||||
|       versioned_symbols_flavour="GNUTLS_" | ||||
|     elif test "x$NSS_ENABLED" == "x1"; then | ||||
|       versioned_symbols_flavour="NSS_" | ||||
|     elif test "x$POLARSSL_ENABLED" == "x1"; then | ||||
|       versioned_symbols_flavour="POLARSSL_" | ||||
|     elif test "x$CYASSL_ENABLED" == "x1"; then | ||||
|       versioned_symbols_flavour="CYASSL_" | ||||
|     elif test "x$AXTLS_ENABLED" == "x1"; then | ||||
|       versioned_symbols_flavour="AXTLS_" | ||||
|     else | ||||
|       versioned_symbols_flavour="" | ||||
|     fi | ||||
|     versioned_symbols="yes" | ||||
|     ;; | ||||
|  | ||||
|   *)   AC_MSG_RESULT(no) | ||||
|     ;; | ||||
|   esac | ||||
| ], [ | ||||
| AC_MSG_RESULT(no) | ||||
| ] | ||||
| ) | ||||
| fi | ||||
|  | ||||
| AC_SUBST(VERSIONED_FLAVOUR, ["$versioned_symbols_flavour"]) | ||||
| AM_CONDITIONAL(VERSIONED_SYMBOLS, test "x$versioned_symbols" = "xyes") | ||||
|  | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Check for the presence of IDN libraries and headers | ||||
| dnl ********************************************************************** | ||||
|  | ||||
| AC_MSG_CHECKING([whether to build with libidn]) | ||||
| OPT_IDN="default" | ||||
| AC_ARG_WITH(libidn, | ||||
| AC_HELP_STRING([--with-libidn=PATH],[Enable libidn usage]) | ||||
| AC_HELP_STRING([--without-libidn],[Disable libidn usage]), | ||||
|   [LIBIDN="$withval"]) | ||||
|  | ||||
| case "$LIBIDN" in | ||||
|   [OPT_IDN=$withval]) | ||||
| case "$OPT_IDN" in | ||||
|   no) | ||||
|        AC_MSG_RESULT(no) | ||||
|     dnl --without-libidn option used | ||||
|     want_idn="no" | ||||
|     AC_MSG_RESULT([no]) | ||||
|     ;; | ||||
|   *)   AC_MSG_RESULT(yes) | ||||
|   default) | ||||
|     dnl configure option not specified | ||||
|     want_idn="yes" | ||||
|     want_idn_path="default" | ||||
|     AC_MSG_RESULT([(assumed) yes]) | ||||
|     ;; | ||||
|   yes) | ||||
|     dnl --with-libidn option used without path | ||||
|     want_idn="yes" | ||||
|     want_idn_path="default" | ||||
|     AC_MSG_RESULT([yes]) | ||||
|     ;; | ||||
|   *) | ||||
|     dnl --with-libidn option used with path | ||||
|     want_idn="yes" | ||||
|     want_idn_path="$withval" | ||||
|     AC_MSG_RESULT([yes ($withval)]) | ||||
|     ;; | ||||
| esac | ||||
|  | ||||
|        idn="" | ||||
|        dnl if there is a given path, check that FIRST | ||||
|        if test -n "$LIBIDN"; then | ||||
|          if test "x$LIBIDN" != "xyes"; then | ||||
|             oldLDFLAGS=$LDFLAGS | ||||
|             oldCPPFLAGS=$CPPFLAGS | ||||
|             LDFLAGS="$LDFLAGS -L$LIBIDN/lib" | ||||
|             CPPFLAGS="$CPPFLAGS -I$LIBIDN/include" | ||||
|             idn="yes" | ||||
|             AC_CHECK_LIB(idn, idna_to_ascii_4i, , | ||||
|                          idn="" | ||||
|                          LDFLAGS=$oldLDFLAGS | ||||
|                          CPPFLAGS=$oldCPPFLAGS) | ||||
| if test "$want_idn" = "yes"; then | ||||
|   dnl idn library support has been requested | ||||
|   clean_CPPFLAGS="$CPPFLAGS" | ||||
|   clean_LDFLAGS="$LDFLAGS" | ||||
|   clean_LIBS="$LIBS" | ||||
|   PKGCONFIG="no" | ||||
|   # | ||||
|   if test "$want_idn_path" != "default"; then | ||||
|     dnl path has been specified | ||||
|     IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig" | ||||
|     CURL_CHECK_PKGCONFIG(libidn, [$IDN_PCDIR]) | ||||
|     if test "$PKGCONFIG" != "no"; then | ||||
|       IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl | ||||
|         $PKGCONFIG --libs-only-l libidn 2>/dev/null` | ||||
|       IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl | ||||
|         $PKGCONFIG --libs-only-L libidn 2>/dev/null` | ||||
|       IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl | ||||
|         $PKGCONFIG --cflags-only-I libidn 2>/dev/null` | ||||
|       IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'` | ||||
|     else | ||||
|       dnl pkg-config not available or provides no info | ||||
|       IDN_LIBS="-lidn" | ||||
|       IDN_LDFLAGS="-L$want_idn_path/lib$libsuff" | ||||
|       IDN_CPPFLAGS="-I$want_idn_path/include" | ||||
|       IDN_DIR="$want_idn_path/lib$libsuff" | ||||
|     fi | ||||
|   else | ||||
|     dnl path not specified | ||||
|     CURL_CHECK_PKGCONFIG(libidn) | ||||
|     if test "$PKGCONFIG" != "no"; then | ||||
|       IDN_LIBS=`$PKGCONFIG --libs-only-l libidn 2>/dev/null` | ||||
|       IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn 2>/dev/null` | ||||
|       IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn 2>/dev/null` | ||||
|       IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'` | ||||
|     else | ||||
|       dnl pkg-config not available or provides no info | ||||
|       IDN_LIBS="-lidn" | ||||
|     fi | ||||
|   fi | ||||
|  | ||||
|        if test "x$idn" != "xyes"; then | ||||
|           dnl check with default paths | ||||
|           idn="yes" | ||||
|           AC_CHECK_LIB(idn, idna_to_ascii_lz, , | ||||
|                        idn="") | ||||
|   # | ||||
|   if test "$PKGCONFIG" != "no"; then | ||||
|     AC_MSG_NOTICE([pkg-config: IDN_LIBS: "$IDN_LIBS"]) | ||||
|     AC_MSG_NOTICE([pkg-config: IDN_LDFLAGS: "$IDN_LDFLAGS"]) | ||||
|     AC_MSG_NOTICE([pkg-config: IDN_CPPFLAGS: "$IDN_CPPFLAGS"]) | ||||
|     AC_MSG_NOTICE([pkg-config: IDN_DIR: "$IDN_DIR"]) | ||||
|   else | ||||
|     AC_MSG_NOTICE([IDN_LIBS: "$IDN_LIBS"]) | ||||
|     AC_MSG_NOTICE([IDN_LDFLAGS: "$IDN_LDFLAGS"]) | ||||
|     AC_MSG_NOTICE([IDN_CPPFLAGS: "$IDN_CPPFLAGS"]) | ||||
|     AC_MSG_NOTICE([IDN_DIR: "$IDN_DIR"]) | ||||
|   fi | ||||
|  | ||||
|        if test "x$idn" = "xyes"; then | ||||
|          curl_idn_msg="enabled" | ||||
|          AC_SUBST(IDN_ENABLED, [1]) | ||||
|   # | ||||
|   CPPFLAGS="$IDN_CPPFLAGS $CPPFLAGS" | ||||
|   LDFLAGS="$IDN_LDFLAGS $LDFLAGS" | ||||
|   LIBS="$IDN_LIBS $LIBS" | ||||
|   # | ||||
|   AC_MSG_CHECKING([if idna_to_ascii_4i can be linked]) | ||||
|   AC_LINK_IFELSE([ | ||||
|     AC_LANG_FUNC_LINK_TRY([idna_to_ascii_4i]) | ||||
|   ],[ | ||||
|     AC_MSG_RESULT([yes]) | ||||
|     tst_links_libidn="yes" | ||||
|   ],[ | ||||
|     AC_MSG_RESULT([no]) | ||||
|     tst_links_libidn="no" | ||||
|   ]) | ||||
|   if test "$tst_links_libidn" = "no"; then | ||||
|     AC_MSG_CHECKING([if idna_to_ascii_lz can be linked]) | ||||
|     AC_LINK_IFELSE([ | ||||
|       AC_LANG_FUNC_LINK_TRY([idna_to_ascii_lz]) | ||||
|     ],[ | ||||
|       AC_MSG_RESULT([yes]) | ||||
|       tst_links_libidn="yes" | ||||
|     ],[ | ||||
|       AC_MSG_RESULT([no]) | ||||
|       tst_links_libidn="no" | ||||
|     ]) | ||||
|   fi | ||||
|   # | ||||
|   if test "$tst_links_libidn" = "yes"; then | ||||
|     AC_DEFINE(HAVE_LIBIDN, 1, [Define to 1 if you have the `idn' library (-lidn).]) | ||||
|     dnl different versions of libidn have different setups of these: | ||||
|     AC_CHECK_FUNCS( idn_free idna_strerror tld_strerror ) | ||||
|     AC_CHECK_HEADERS( idn-free.h tld.h ) | ||||
|     if test "x$ac_cv_header_tld_h" = "xyes"; then | ||||
|       AC_SUBST([IDN_ENABLED], [1]) | ||||
|       curl_idn_msg="enabled" | ||||
|       if test -n "$IDN_DIR"; then | ||||
|         LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR" | ||||
|         export LD_LIBRARY_PATH | ||||
|         AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH]) | ||||
|       fi | ||||
|     else | ||||
|       AC_MSG_WARN([Libraries for IDN support too old: IDN disabled]) | ||||
|       CPPFLAGS="$clean_CPPFLAGS" | ||||
|       LDFLAGS="$clean_LDFLAGS" | ||||
|       LIBS="$clean_LIBS" | ||||
|     fi | ||||
|   else | ||||
|     AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) | ||||
|     CPPFLAGS="$clean_CPPFLAGS" | ||||
|     LDFLAGS="$clean_LDFLAGS" | ||||
|     LIBS="$clean_LIBS" | ||||
|   fi | ||||
| fi | ||||
|  | ||||
|        ;; | ||||
| esac | ||||
|  | ||||
|  | ||||
| dnl Let's hope this split URL remains working: | ||||
| @@ -3108,6 +3269,7 @@ AC_CONFIG_FILES([Makefile \ | ||||
|            include/curl/Makefile \ | ||||
|            src/Makefile \ | ||||
|            lib/Makefile \ | ||||
|            lib/libcurl.vers \ | ||||
|            tests/Makefile \ | ||||
|            tests/data/Makefile \ | ||||
|            tests/server/Makefile \ | ||||
|   | ||||
							
								
								
									
										8
									
								
								docs/FAQ
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								docs/FAQ
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| Updated: March 8, 2011 (http://curl.haxx.se/docs/faq.html) | ||||
| Updated: December 7, 2011 (http://curl.haxx.se/docs/faq.html) | ||||
|                                   _   _ ____  _ | ||||
|                               ___| | | |  _ \| | | ||||
|                              / __| | | | |_) | | | ||||
| @@ -726,6 +726,12 @@ FAQ | ||||
|  | ||||
|     curl --header "Host: www.example.com" http://127.0.0.1/ | ||||
|  | ||||
|   You can also opt to add faked host name entries to curl with the --resolve | ||||
|   option. That has the added benefit that things like redirects will also work | ||||
|   properly. The above operation would instead be done as: | ||||
|  | ||||
|     curl --resolve www.example.com:80:127.0.0.1 http://www.example.com/ | ||||
|  | ||||
|   3.20 How to SFTP from my user's home directory? | ||||
|  | ||||
|   Contrary to how FTP works, SFTP and SCP URLs specify the exact directory to | ||||
|   | ||||
							
								
								
									
										0
									
								
								docs/INSTALL.cmake
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/INSTALL.cmake
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @@ -68,7 +68,7 @@ Portability | ||||
|  GNU Autoconf 2.57 | ||||
|  GNU Automake 1.7 (we currently avoid 1.10 due to Solaris-related bugs) | ||||
|  GNU M4       1.4 | ||||
|  perl         4 | ||||
|  perl         5.004 | ||||
|  roffit       0.5 | ||||
|  groff        ? (any version that supports "groff -Tps -man [in] [out]") | ||||
|  ps2pdf (gs)  ? | ||||
|   | ||||
| @@ -3,6 +3,15 @@ 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! | ||||
|  | ||||
| 78. curl and libcurl don't always signal the client properly when "sending" | ||||
|   zero bytes files - it makes for example the command line client not creating | ||||
|   any file at all. Like when using FTP. | ||||
|   http://curl.haxx.se/bug/view.cgi?id=3438362 | ||||
|  | ||||
| 77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it | ||||
|   "absuses" the underlying connection re-use system and if connections are | ||||
|   forced to close they break the NTLM support. | ||||
|  | ||||
| 76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on | ||||
|   that platform), and long is only 32 bits. It makes it impossible for | ||||
|   curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET | ||||
| @@ -12,12 +21,6 @@ may have been fixed since this was written! | ||||
|   http://curl.haxx.se/mail/lib-2009-10/0024.html | ||||
|   http://curl.haxx.se/bug/view.cgi?id=2944325 | ||||
|  | ||||
| 74. The HTTP spec allows headers to be merged and become comma-separated | ||||
|   instead of being repeated several times. This also include Authenticate: and | ||||
|   Proxy-Authenticate: headers and while this hardly every happens in real life | ||||
|   it will confuse libcurl which does not properly support it for all headers - | ||||
|   like those Authenticate headers. | ||||
|  | ||||
| 73. if a connection is made to a FTP server but the server then just never | ||||
|   sends the 220 response or otherwise is dead slow, libcurl will not | ||||
|   acknowledge the connection timeout during that phase but only the "real" | ||||
|   | ||||
| @@ -328,7 +328,7 @@ POST (HTTP) | ||||
|   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 (from | ||||
|   an earlier file if several files are specified in a list) or else it will | ||||
|   using the default type 'text/plain'. | ||||
|   use the default type 'application/octet-stream'. | ||||
|  | ||||
|   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 | ||||
|   | ||||
							
								
								
									
										0
									
								
								docs/README.cmake
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/README.cmake
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										35
									
								
								docs/THANKS
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								docs/THANKS
									
									
									
									
									
								
							| @@ -9,12 +9,16 @@ Aaron Orenstein | ||||
| Adam D. Moss | ||||
| Adam Light | ||||
| Adam Piggott | ||||
| Adam Tkac | ||||
| Adrian Schuur | ||||
| Adriano Meirelles | ||||
| Akos Pasztory | ||||
| Alan Pinstein | ||||
| Albert Chin | ||||
| Albert Chin-A-Young | ||||
| Albert Choy | ||||
| Ale Vesely | ||||
| Alejandro Alvarez | ||||
| Aleksandar Milivojevic | ||||
| Alessandro Vesely | ||||
| Alex Bligh | ||||
| @@ -30,6 +34,7 @@ Alexander Zhuravlev | ||||
| Alexey Borzov | ||||
| Alexey Pesternikov | ||||
| Alexey Simak | ||||
| Alexey Zakhlestin | ||||
| Alexis Carvalho | ||||
| Alfred Gebert | ||||
| Allen Pulsifer | ||||
| @@ -64,6 +69,7 @@ Andy Tsouladze | ||||
| Angus Mackay | ||||
| Anthony Bryan | ||||
| Antoine Calando | ||||
| Anton Bychkov | ||||
| Anton Kalmykov | ||||
| Arkadiusz Miskiewicz | ||||
| Armel Asselin | ||||
| @@ -81,6 +87,7 @@ Ben Greear | ||||
| Ben Madsen | ||||
| Ben Noordhuis | ||||
| Ben Van Hof | ||||
| Ben Winslow | ||||
| Benbuck Nason | ||||
| Benjamin Gerard | ||||
| Bernard Leak | ||||
| @@ -126,6 +133,7 @@ Chris Gaukroger | ||||
| Chris Maltby | ||||
| Chris Mumford | ||||
| Chris Smowton | ||||
| Christian Hagele | ||||
| Christian Krause | ||||
| Christian Kurz | ||||
| Christian Robottom Reis | ||||
| @@ -136,6 +144,7 @@ Christophe Legry | ||||
| Christopher Conroy | ||||
| Christopher Palow | ||||
| Christopher R. Palmer | ||||
| Christopher Stone | ||||
| Ciprian Badescu | ||||
| Claes Jakobsson | ||||
| Clarence Gardner | ||||
| @@ -150,6 +159,7 @@ Craig A West | ||||
| Craig Davison | ||||
| Craig Markwardt | ||||
| Cris Bailiff | ||||
| Cristian Rodriguez | ||||
| Curt Bogmine | ||||
| Cyrill Osterwalder | ||||
| Dagobert Michelsen | ||||
| @@ -220,6 +230,7 @@ Dmitry Rechkin | ||||
| Dolbneff A.V | ||||
| Domenico Andreoli | ||||
| Dominick Meglio | ||||
| Dominique Leuenberger | ||||
| Doug Kaufman | ||||
| Doug Porter | ||||
| Douglas E. Wegscheid | ||||
| @@ -260,6 +271,7 @@ Erwin Authried | ||||
| Eugene Kotlyarov | ||||
| Evan Jordan | ||||
| Eygene Ryabinkin | ||||
| Fabian Hiernaux | ||||
| Fabian Keil | ||||
| Fabrizio Ammollo | ||||
| Fedor Karpelevitch | ||||
| @@ -272,11 +284,13 @@ Frank Keeney | ||||
| Frank McGeough | ||||
| Frank Meier | ||||
| Frank Ticheler | ||||
| Frank Van Uffelen | ||||
| Fred Machado | ||||
| Fred New | ||||
| Fred Noz | ||||
| Frederic Lepied | ||||
| Gabriel Kuri | ||||
| Garrett Holmstrom | ||||
| Gary Maxwell | ||||
| Gautam Kachroo | ||||
| Gautam Mani | ||||
| @@ -300,6 +314,7 @@ Giuseppe Attardi | ||||
| Giuseppe D'Ambrosio | ||||
| Glen Nakamura | ||||
| Glen Scott | ||||
| Gokhan Sengun | ||||
| Grant Erickson | ||||
| Greg Hewgill | ||||
| Greg Morse | ||||
| @@ -325,6 +340,7 @@ Heinrich Ko | ||||
| Hendrik Visage | ||||
| Henrik Storner | ||||
| Henry Ludemann | ||||
| Herve Amblard | ||||
| Hidemoto Nakada | ||||
| Hoi-Ho Chan | ||||
| Hongli Lai | ||||
| @@ -386,11 +402,13 @@ Jeffrey Pohlmeyer | ||||
| Jeremy Friesner | ||||
| Jerome Muffat-Meridol | ||||
| Jerome Vouillon | ||||
| Jerry Wu | ||||
| Jes Badwal | ||||
| Jesper Jensen | ||||
| Jesse Noller | ||||
| Jim Drash | ||||
| Jim Freeman | ||||
| Jim Hollinger | ||||
| Jim Meyering | ||||
| Jocelyn Jaubert | ||||
| Joe Halpin | ||||
| @@ -434,6 +452,7 @@ Juergen Wilke | ||||
| Jukka Pihl | ||||
| Julian Noble | ||||
| Julien Chaffraix | ||||
| Julien Royer | ||||
| Jun-ichiro itojun Hagino | ||||
| Jurij Smakov | ||||
| Justin Fletcher | ||||
| @@ -505,18 +524,21 @@ Luke Call | ||||
| Luong Dinh Dung | ||||
| Maciej Karpiuk | ||||
| Maciej W. Rozycki | ||||
| Mandy Wu | ||||
| Manfred Schwarb | ||||
| Manuel Massing | ||||
| Marc Boucher | ||||
| Marc Kleine-Budde | ||||
| Marcel Roelofs | ||||
| Marcelo Juchem | ||||
| Marcin Adamski | ||||
| Marcin Konicki | ||||
| Marco G. Salvagno | ||||
| Marco Maggi | ||||
| Marcus Sundberg | ||||
| Marcus Webster | ||||
| Mario Schroeder | ||||
| Mark Brand | ||||
| Mark Butler | ||||
| Mark Davies | ||||
| Mark Eichin | ||||
| @@ -566,6 +588,7 @@ Michael Goffioul | ||||
| Michael Jahn | ||||
| Michael Jerris | ||||
| Michael Mealling | ||||
| Michael Mueller | ||||
| Michael Smith | ||||
| Michael Stillwell | ||||
| Michael Wallner | ||||
| @@ -620,6 +643,7 @@ Olaf St | ||||
| Oren Tirosh | ||||
| Ori Avtalion | ||||
| P R Schaffner | ||||
| Paolo Piacentini | ||||
| Pascal Terjan | ||||
| Pasha Kuznetsov | ||||
| Pat Ray | ||||
| @@ -628,6 +652,7 @@ Patrick Monnerat | ||||
| Patrick Scott | ||||
| Patrick Smith | ||||
| Patrik Thunstrom | ||||
| Pau Garcia i Quiles | ||||
| Paul Harrington | ||||
| Paul Howarth | ||||
| Paul Marquis | ||||
| @@ -645,6 +670,7 @@ Pete Su | ||||
| Peter Bray | ||||
| Peter Forret | ||||
| Peter Heuchert | ||||
| Peter Hjalmarsson | ||||
| Peter Korsgaard | ||||
| Peter Lamberg | ||||
| Peter O'Gorman | ||||
| @@ -783,6 +809,7 @@ Stephen Kick | ||||
| Stephen More | ||||
| Sterling Hughes | ||||
| Steve Green | ||||
| Steve Holme | ||||
| Steve Lhomme | ||||
| Steve Little | ||||
| Steve Marx | ||||
| @@ -791,6 +818,7 @@ Steve Roskowski | ||||
| Steven Bazyl | ||||
| Steven G. Johnson | ||||
| Steven M. Schweda | ||||
| Steven Parkes | ||||
| Stoned Elipot | ||||
| Sven Anders | ||||
| Sven Neuhaus | ||||
| @@ -798,10 +826,12 @@ Sven Wegener | ||||
| S<EFBFBD>bastien Willemijns | ||||
| T. Bharath | ||||
| T. Yamada | ||||
| Taneli Vahakangas | ||||
| Tanguy Fautre | ||||
| Temprimus | ||||
| Thomas J. Moore | ||||
| Thomas Klausner | ||||
| Thomas L. Shinnick | ||||
| Thomas Lopatic | ||||
| Thomas Schwinge | ||||
| Thomas Tonino | ||||
| @@ -810,6 +840,7 @@ Tim Baker | ||||
| Tim Bartley | ||||
| Tim Chen | ||||
| Tim Costello | ||||
| Tim Harder | ||||
| Tim Newsome | ||||
| Tim Sneddon | ||||
| Tinus van den Berg | ||||
| @@ -825,6 +856,7 @@ Tom Mattison | ||||
| Tom Moers | ||||
| Tom Mueller | ||||
| Tom Regner | ||||
| Tom Wright | ||||
| Tom Zerucha | ||||
| Tomas Pospisek | ||||
| Tomas Szepe | ||||
| @@ -854,6 +886,7 @@ Vincent Sanders | ||||
| Vincent Torri | ||||
| Vlad Grachov | ||||
| Vlad Ureche | ||||
| Vladimir Grishchenko | ||||
| Vladimir Lazarenko | ||||
| Vojtech Janota | ||||
| Vojtech Minarik | ||||
| @@ -866,10 +899,12 @@ Wesley Miaw | ||||
| Wez Furlong | ||||
| Wilfredo Sanchez | ||||
| Wojciech Zwiefka | ||||
| Wu Yongzheng | ||||
| Xavier Bouchoux | ||||
| Yang Tse | ||||
| Yarram Sunil | ||||
| Yehoshua Hershberg | ||||
| Yukihiro Kawada | ||||
| Yuriy Sosov | ||||
| Yves Lejeune | ||||
| Zmey Petroff | ||||
|   | ||||
							
								
								
									
										24
									
								
								docs/TODO
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								docs/TODO
									
									
									
									
									
								
							| @@ -17,6 +17,7 @@ | ||||
|  1.4 signal-based resolver timeouts | ||||
|  1.5 get rid of PATH_MAX | ||||
|  1.6 progress callback without doubles | ||||
|  1.7 Happy Eyeball dual stack connect | ||||
|  | ||||
|  2. libcurl - multi interface | ||||
|  2.1 More non-blocking | ||||
| @@ -99,6 +100,7 @@ | ||||
|  15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE | ||||
|  15.7 remove progress meter from libcurl | ||||
|  15.8 remove 'curl_httppost' from public | ||||
|  15.9 have form functions use CURL handle argument | ||||
|  | ||||
| ============================================================================== | ||||
|  | ||||
| @@ -146,6 +148,19 @@ | ||||
|  have both co-exist for a forseeable time until we can remove the double-using | ||||
|  one. | ||||
|  | ||||
| 1.7 Happy Eyeball dual stack connect | ||||
|  | ||||
|  In order to make alternative technologies not suffer when transitioning, like | ||||
|  when introducing IPv6 as an alternative to IPv4 and there are more than one | ||||
|  option existing simultaneously there are reasons to reconsider internal | ||||
|  choices. | ||||
|  | ||||
|  To make libcurl do blazing fast IPv6 in a dual-stack configuration, this needs | ||||
|  to be addressed: | ||||
|  | ||||
|     http://tools.ietf.org/html/draft-ietf-v6ops-happy-eyeballs-07 | ||||
|  | ||||
|  | ||||
| 2. libcurl - multi interface | ||||
|  | ||||
| 2.1 More non-blocking | ||||
| @@ -155,7 +170,6 @@ | ||||
|  | ||||
|  - Name resolves on non-windows unless c-ares is used | ||||
|  - NSS SSL connections | ||||
|  - Active FTP connections | ||||
|  - HTTP proxy CONNECT operations | ||||
|  - SOCKS proxy handshakes | ||||
|  - file:// transfers | ||||
| @@ -559,3 +573,11 @@ to provide the data to send. | ||||
|  | ||||
|  Changing them to return a private handle will benefit the implementation and | ||||
|  allow us much greater freedoms while still maintining a solid API and ABI. | ||||
|  | ||||
| 15.9 have form functions use CURL handle argument | ||||
|  | ||||
|  curl_formadd() and curl_formget() both currently have no CURL handle | ||||
|  argument, but both can use a callback that is set in the easy handle, and | ||||
|  thus curl_formget() with callback cannot function without first having | ||||
|  curl_easy_perform() (or similar) called - which is hard to grasp and a design | ||||
|  mistake. | ||||
|   | ||||
							
								
								
									
										36
									
								
								docs/curl.1
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								docs/curl.1
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
| .\" *                            | (__| |_| |  _ <| |___ | ||||
| .\" *                             \___|\___/|_| \_\_____| | ||||
| .\" * | ||||
| .\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * | ||||
| .\" * This software is licensed as described in the file COPYING, which | ||||
| .\" * you should have received as part of this distribution. The terms | ||||
| @@ -110,7 +110,8 @@ the --option version of them. (This concept with --no options was added in | ||||
| 7.19.0. Previously most options were toggled on/off on repeated use of the | ||||
| same command line option.) | ||||
| .IP "-#, --progress-bar" | ||||
| Make curl display progress information as a progress bar instead of the | ||||
| Make curl display progress as a simple progress bar instead of the standard, | ||||
| more informational, meter. | ||||
| .IP "-0, --http1.0" | ||||
| (HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its | ||||
| internally preferred: HTTP 1.1. | ||||
| @@ -363,7 +364,7 @@ passive mode you need to not use \fI-P, --ftp-port\fP or force it with | ||||
| transfers. Curl will normally always first attempt to use EPSV before PASV, | ||||
| but with this option, it will not try using EPSV. | ||||
|  | ||||
| \fB--epsv\fP can be used to explicitly enable EPRT again and \fB--no-epsv\fP | ||||
| \fB--epsv\fP can be used to explicitly enable EPSV again and \fB--no-epsv\fP | ||||
| is an alias for \fB--disable-epsv\fP. | ||||
|  | ||||
| Disabling EPSV only changes the passive behavior. If you want to switch to | ||||
| @@ -433,13 +434,15 @@ may be loaded. | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "--capath <CA certificate directory>" | ||||
| (SSL) Tells curl to use the specified certificate directory to verify the | ||||
| peer. The certificates must be in PEM format, and if curl is built against | ||||
| OpenSSL, the directory must have been processed using the c_rehash utility | ||||
| supplied with OpenSSL. Using \fI--capath\fP can allow OpenSSL-powered curl to | ||||
| make SSL-connections much more efficiently than using \fI--cacert\fP if the | ||||
| \fI--cacert\fP file contains many CA certificates. | ||||
| peer. Multiple paths can be provided by separating them with ":" (e.g. | ||||
| \&"path1:path2:path3"). The certificates must be in PEM format, and if curl is | ||||
| built against OpenSSL, the directory must have been processed using the | ||||
| c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow | ||||
| OpenSSL-powered curl to make SSL-connections much more efficiently than using | ||||
| \fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| If this option is set, the default capath value will be ignored, and if it is | ||||
| used several times, the last one will be used. | ||||
| .IP "-f, --fail" | ||||
| (HTTP) Fail silently (no output at all) on server errors. This is mostly done | ||||
| to better enable scripts etc to better deal with failed attempts. In | ||||
| @@ -592,7 +595,9 @@ header will be used instead of the internal one. This allows you to make even | ||||
| trickier stuff than curl would normally do. You should not replace internally | ||||
| set headers without knowing perfectly well what you're doing. Remove an | ||||
| internal header by giving a replacement without content on the right side of | ||||
| the colon, as in: -H \&"Host:". | ||||
| the colon, as in: -H \&"Host:". If you send the custom header with no-value then | ||||
| its header must be terminated with a semicolon, such as \-H "X-Custom-Header;" | ||||
| to send "X-Custom-Header:". | ||||
|  | ||||
| curl will make sure that each header you add/replace is sent with the proper | ||||
| end-of-line marker, you should thus \fBnot\fP add that as a part of the header | ||||
| @@ -1319,8 +1324,7 @@ implementation does not.  The option \fI--socks5-gssapi-nec\fP allows the | ||||
| unprotected exchange of the protection mode negotiation. (Added in 7.19.4). | ||||
| .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. | ||||
| is a plain '-', it is instead written to stdout. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "-t, --telnet-option <OPT=val>" | ||||
| @@ -1592,6 +1596,14 @@ Specifies a custom FTP command to use instead of LIST when doing file lists | ||||
| with FTP. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
|  | ||||
| .IP "--xattr" | ||||
| When saving output to a file, this option tells curl to store certain file | ||||
| metadata in extened file attributes. Currently, the URL is stored in the | ||||
| xdg.origin.url attribute and, for HTTP, the content type is stored in | ||||
| the mime_type attribute. If the file system does not support extended | ||||
| attributes, a warning is issued. | ||||
|  | ||||
| .IP "-y, --speed-time <time>" | ||||
| If a download is slower than speed-limit bytes per second during a speed-time | ||||
| period, the download gets aborted. If speed-time is used, the default | ||||
|   | ||||
							
								
								
									
										5
									
								
								docs/examples/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								docs/examples/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -18,14 +18,18 @@ http-post | ||||
| httpcustomheader | ||||
| httpput | ||||
| https | ||||
| imap | ||||
| multi-app | ||||
| multi-debugcallback | ||||
| multi-double | ||||
| multi-post | ||||
| multi-single | ||||
| persistant | ||||
| pop3s | ||||
| pop3slist | ||||
| post-callback | ||||
| postit2 | ||||
| progressfunc | ||||
| resolve | ||||
| rtsp | ||||
| sendrecv | ||||
| @@ -36,3 +40,4 @@ simplesmtp | ||||
| simplessl | ||||
| smtp-multi | ||||
| smtp-tls | ||||
| url2file | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
| AUTOMAKE_OPTIONS = foreign nostdinc | ||||
|  | ||||
| EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \ | ||||
| 	makefile.dj $(COMPLICATED_EXAMPLES) | ||||
| 	Makefile.netware makefile.dj printf_macro.h $(COMPLICATED_EXAMPLES) | ||||
|  | ||||
| # Specify our include paths here, and do it relative to $(top_srcdir) and | ||||
| # $(top_builddir), to ensure that these paths which belong to the library | ||||
|   | ||||
| @@ -4,7 +4,8 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \ | ||||
|   https multi-app multi-debugcallback multi-double multi-post multi-single \ | ||||
|   persistant post-callback postit2 sepheaders simple simplepost simplessl  \ | ||||
|   sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \ | ||||
|   smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve | ||||
|   smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \ | ||||
|   progressfunc pop3s pop3slist imap url2file | ||||
|  | ||||
| # These examples require external dependencies that may not be commonly | ||||
| # available on POSIX systems, so don't bother attempting to compile them here. | ||||
|   | ||||
| @@ -19,31 +19,50 @@ | ||||
| # KIND, either express or implied. | ||||
| # | ||||
| ########################################################################### | ||||
| ######################################################################### | ||||
| # | ||||
| ## Makefile for building curl examples with MingW32 | ||||
| ## and optionally OpenSSL (0.9.8), libssh2 (0.18), zlib (1.2.3) | ||||
| ## Makefile for building curl examples with MingW (GCC-3.2 or later) | ||||
| ## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3) | ||||
| ## | ||||
| ## Usage: | ||||
| ## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [SSPI=1] [IPV6=1] [DYN=1] | ||||
| ## Usage:   mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...] | ||||
| ## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn | ||||
| ## | ||||
| ## Hint: you can also set environment vars to control the build, f.e.: | ||||
| ## set ZLIB_PATH=c:/zlib-1.2.3 | ||||
| ## set ZLIB_PATH=c:/zlib-1.2.5 | ||||
| ## set ZLIB=1 | ||||
| ## | ||||
| ######################################################################### | ||||
| # | ||||
| ########################################################################### | ||||
|  | ||||
| # Edit the path below to point to the base of your Zlib sources. | ||||
| ifndef ZLIB_PATH | ||||
| ZLIB_PATH = ../../zlib-1.2.3 | ||||
| ZLIB_PATH = ../../../zlib-1.2.5 | ||||
| endif | ||||
| # Edit the path below to point to the base of your OpenSSL package. | ||||
| ifndef OPENSSL_PATH | ||||
| OPENSSL_PATH = ../../openssl-0.9.8k | ||||
| OPENSSL_PATH = ../../../openssl-0.9.8r | ||||
| endif | ||||
| ifndef OPENSSL_LIBPATH | ||||
| OPENSSL_LIBPATH = $(OPENSSL_PATH)/out | ||||
| endif | ||||
| ifndef OPENSSL_LIBS | ||||
| OPENSSL_LIBS = -leay32 -lssl32 | ||||
| endif | ||||
| # Edit the path below to point to the base of your LibSSH2 package. | ||||
| ifndef LIBSSH2_PATH | ||||
| LIBSSH2_PATH = ../../libssh2-1.2 | ||||
| LIBSSH2_PATH = ../../../libssh2-1.3.0 | ||||
| endif | ||||
| # Edit the path below to point to the base of your librtmp package. | ||||
| ifndef LIBRTMP_PATH | ||||
| LIBRTMP_PATH = ../../../librtmp-2.3 | ||||
| endif | ||||
| # Edit the path below to point to the base of your libidn package. | ||||
| ifndef LIBIDN_PATH | ||||
| LIBIDN_PATH = ../../../libidn-1.18 | ||||
| endif | ||||
| # Edit the path below to point to the base of your MS IDN package. | ||||
| # Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 | ||||
| # http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815 | ||||
| ifndef WINIDN_PATH | ||||
| WINIDN_PATH = ../../../Microsoft IDN Mitigation APIs | ||||
| endif | ||||
| # Edit the path below to point to the base of your Novell LDAP NDK. | ||||
| ifndef LDAP_SDK | ||||
| @@ -51,25 +70,76 @@ LDAP_SDK = c:/novell/ndk/cldapsdk/win32 | ||||
| endif | ||||
|  | ||||
| PROOT = ../.. | ||||
| ARES_LIB = $(PROOT)/ares | ||||
|  | ||||
| SSL = 1 | ||||
| ZLIB = 1 | ||||
| # Edit the path below to point to the base of your c-ares package. | ||||
| ifndef LIBCARES_PATH | ||||
| LIBCARES_PATH = $(PROOT)/ares | ||||
| endif | ||||
|  | ||||
| # Edit the var below to set to your architecture or set environment var. | ||||
| ifndef ARCH | ||||
| ARCH = w32 | ||||
| endif | ||||
|  | ||||
| CC = gcc | ||||
| CFLAGS = -g -O2 -Wall | ||||
| CFLAGS += -fno-strict-aliasing | ||||
| ifeq ($(ARCH),w64) | ||||
| CFLAGS += -D_AMD64_ | ||||
| endif | ||||
| # comment LDFLAGS below to keep debug info | ||||
| LDFLAGS = -s | ||||
| RC = windres | ||||
| RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i | ||||
| RM = del /q /f > NUL 2>&1 | ||||
|  | ||||
| RM = del /q /f 2>NUL | ||||
| CP = copy | ||||
|  | ||||
| ######################################################## | ||||
| ## Nothing more to do below this line! | ||||
|  | ||||
| ifeq ($(findstring -dyn,$(CFG)),-dyn) | ||||
| DYN = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ares,$(CFG)),-ares) | ||||
| ARES = 1 | ||||
| endif | ||||
| ifeq ($(findstring -rtmp,$(CFG)),-rtmp) | ||||
| RTMP = 1 | ||||
| SSL = 1 | ||||
| ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ssh2,$(CFG)),-ssh2) | ||||
| SSH2 = 1 | ||||
| SSL = 1 | ||||
| ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ssl,$(CFG)),-ssl) | ||||
| SSL = 1 | ||||
| endif | ||||
| ifeq ($(findstring -zlib,$(CFG)),-zlib) | ||||
| ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -idn,$(CFG)),-idn) | ||||
| IDN = 1 | ||||
| endif | ||||
| ifeq ($(findstring -winidn,$(CFG)),-winidn) | ||||
| WINIDN = 1 | ||||
| endif | ||||
| ifeq ($(findstring -sspi,$(CFG)),-sspi) | ||||
| SSPI = 1 | ||||
| endif | ||||
| ifeq ($(findstring -spnego,$(CFG)),-spnego) | ||||
| SPNEGO = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ldaps,$(CFG)),-ldaps) | ||||
| LDAPS = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ipv6,$(CFG)),-ipv6) | ||||
| IPV6 = 1 | ||||
| endif | ||||
|  | ||||
| INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib | ||||
| LINK = $(CC) $(LDFLAGS) -o $@ | ||||
|  | ||||
| ifdef DYN | ||||
|   curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll | ||||
| @@ -81,34 +151,45 @@ else | ||||
| endif | ||||
| ifdef ARES | ||||
|   ifndef DYN | ||||
|     curl_DEPENDENCIES += $(ARES_LIB)/libcares.a | ||||
|     curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a | ||||
|   endif | ||||
|   CFLAGS += -DUSE_ARES | ||||
|   curl_LDADD += -L$(ARES_LIB) -lcares | ||||
|   curl_LDADD += -L"$(LIBCARES_PATH)" -lcares | ||||
| endif | ||||
| ifdef RTMP | ||||
|   CFLAGS += -DUSE_LIBRTMP | ||||
|   curl_LDADD += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm | ||||
| endif | ||||
| ifdef SSH2 | ||||
|   CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H | ||||
|   curl_LDADD += -L$(LIBSSH2_PATH)/win32 -lssh2 | ||||
|   curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2 | ||||
| endif | ||||
| ifdef SSL | ||||
|   INCLUDES += -I"$(OPENSSL_PATH)/outinc" | ||||
|   CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H | ||||
|   ifdef DYN | ||||
|     curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32 | ||||
|   else | ||||
|     curl_LDADD += -L$(OPENSSL_PATH)/out -lssl -lcrypto -lgdi32 | ||||
|   endif | ||||
|   curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) | ||||
| endif | ||||
| ifdef ZLIB | ||||
|   INCLUDES += -I"$(ZLIB_PATH)" | ||||
|   CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H | ||||
|   curl_LDADD += -L$(ZLIB_PATH) -lz | ||||
|   curl_LDADD += -L"$(ZLIB_PATH)" -lz | ||||
| endif | ||||
| ifdef IDN | ||||
|   CFLAGS += -DUSE_LIBIDN | ||||
|   curl_LDADD += -L"$(LIBIDN_PATH)/lib" -lidn | ||||
| else | ||||
| ifdef WINIDN | ||||
|   CFLAGS += -DUSE_WIN32_IDN | ||||
|   curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz | ||||
| endif | ||||
| endif | ||||
| ifdef SSPI | ||||
|   CFLAGS += -DUSE_WINDOWS_SSPI | ||||
| endif | ||||
| ifdef SPNEGO | ||||
|   CFLAGS += -DHAVE_SPNEGO | ||||
| endif | ||||
| ifdef IPV6 | ||||
|   CFLAGS += -DENABLE_IPV6 | ||||
|   CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501 | ||||
| endif | ||||
| ifdef LDAPS | ||||
|   CFLAGS += -DHAVE_LDAP_SSL | ||||
| @@ -127,28 +208,28 @@ curl_LDADD += -lwldap32 | ||||
| endif | ||||
| endif | ||||
| curl_LDADD += -lws2_32 | ||||
| COMPILE = $(CC) $(INCLUDES) $(CFLAGS) | ||||
|  | ||||
| # Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines | ||||
| include Makefile.inc | ||||
|  | ||||
| example_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS))) | ||||
|  | ||||
| .SUFFIXES: .rc .res .o .exe | ||||
| check_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS))) | ||||
| check_PROGRAMS += ftpuploadresume.exe synctime.exe | ||||
|  | ||||
|  | ||||
| all: $(example_PROGRAMS) | ||||
| all: $(check_PROGRAMS) | ||||
|  | ||||
| .o.exe: $(curl_DEPENDENCIES) | ||||
| 	$(LINK) $< $(curl_LDADD) | ||||
| %.exe: %.o $(curl_DEPENDENCIES) | ||||
| 	$(CC) $(LDFLAGS) -o $@ $< $(curl_LDADD) | ||||
|  | ||||
| .c.o: | ||||
| 	$(COMPILE) -c $< | ||||
| %.o: %.c | ||||
| 	$(CC) $(INCLUDES) $(CFLAGS) -c $< | ||||
|  | ||||
| .rc.res: | ||||
| %.res: %.rc | ||||
| 	$(RC) $(RCFLAGS) $< -o $@ | ||||
|  | ||||
| clean: | ||||
| 	$(RM) $(example_PROGRAMS) | ||||
| 	-$(RM) $(check_PROGRAMS:.exe=.o) | ||||
|  | ||||
| distclean vclean: clean | ||||
| 	-$(RM) $(check_PROGRAMS) | ||||
|  | ||||
|   | ||||
							
								
								
									
										441
									
								
								docs/examples/Makefile.netware
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								docs/examples/Makefile.netware
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,441 @@ | ||||
| ################################################################# | ||||
| # | ||||
| ## Makefile for building curl.nlm (NetWare version - gnu make) | ||||
| ## Use: make -f Makefile.netware | ||||
| ## | ||||
| ## Comments to: Guenter Knauf http://www.gknw.net/phpbb | ||||
| # | ||||
| ################################################################# | ||||
|  | ||||
| # Edit the path below to point to the base of your Novell NDK. | ||||
| ifndef NDKBASE | ||||
| NDKBASE	= c:/novell | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your Zlib sources. | ||||
| ifndef ZLIB_PATH | ||||
| ZLIB_PATH = ../../../zlib-1.2.5 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your OpenSSL package. | ||||
| ifndef OPENSSL_PATH | ||||
| OPENSSL_PATH = ../../../openssl-0.9.8r | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your LibSSH2 package. | ||||
| ifndef LIBSSH2_PATH | ||||
| LIBSSH2_PATH = ../../../libssh2-1.3.0 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your axTLS package. | ||||
| ifndef AXTLS_PATH | ||||
| AXTLS_PATH = ../../../axTLS-1.2.7 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your libidn package. | ||||
| ifndef LIBIDN_PATH | ||||
| LIBIDN_PATH = ../../../libidn-1.18 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your librtmp package. | ||||
| ifndef LIBRTMP_PATH | ||||
| LIBRTMP_PATH = ../../../librtmp-2.3 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your fbopenssl package. | ||||
| ifndef FBOPENSSL_PATH | ||||
| FBOPENSSL_PATH = ../../fbopenssl-0.4 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your c-ares package. | ||||
| ifndef LIBCARES_PATH | ||||
| LIBCARES_PATH = ../../ares | ||||
| endif | ||||
|  | ||||
| ifndef INSTDIR | ||||
| INSTDIR	= ..$(DS)..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw | ||||
| endif | ||||
|  | ||||
| # Edit the vars below to change NLM target settings. | ||||
| TARGET  = examples | ||||
| VERSION	= $(LIBCURL_VERSION) | ||||
| COPYR	= Copyright (C) $(LIBCURL_COPYRIGHT_STR) | ||||
| DESCR	= cURL ($(LIBARCH)) | ||||
| MTSAFE	= YES | ||||
| STACK	= 8192 | ||||
| SCREEN	= Example Program | ||||
| # Comment the line below if you dont want to load protected automatically. | ||||
| # LDRING = 3 | ||||
|  | ||||
| # Uncomment the next line to enable linking with POSIX semantics. | ||||
| # POSIXFL = 1 | ||||
|  | ||||
| # Edit the var below to point to your lib architecture. | ||||
| ifndef LIBARCH | ||||
| LIBARCH = LIBC | ||||
| endif | ||||
|  | ||||
| # must be equal to NDEBUG or DEBUG, CURLDEBUG | ||||
| ifndef DB | ||||
| DB	= NDEBUG | ||||
| endif | ||||
| # Optimization: -O<n> or debugging: -g | ||||
| ifeq ($(DB),NDEBUG) | ||||
| 	OPT	= -O2 | ||||
| 	OBJDIR	= release | ||||
| else | ||||
| 	OPT	= -g | ||||
| 	OBJDIR	= debug | ||||
| endif | ||||
|  | ||||
| # The following lines defines your compiler. | ||||
| ifdef CWFolder | ||||
| 	METROWERKS = $(CWFolder) | ||||
| endif | ||||
| ifdef METROWERKS | ||||
| 	# MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support | ||||
| 	MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support | ||||
| 	CC = mwccnlm | ||||
| else | ||||
| 	CC = gcc | ||||
| endif | ||||
| PERL	= perl | ||||
| # Here you can find a native Win32 binary of the original awk: | ||||
| # http://www.gknw.net/development/prgtools/awk-20100523.zip | ||||
| AWK	= awk | ||||
| CP	= cp -afv | ||||
| MKDIR	= mkdir | ||||
| # RM	= rm -f | ||||
| # If you want to mark the target as MTSAFE you will need a tool for | ||||
| # generating the xdc data for the linker; here's a minimal tool: | ||||
| # http://www.gknw.net/development/prgtools/mkxdc.zip | ||||
| MPKXDC	= mkxdc | ||||
|  | ||||
| # LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH)) | ||||
| LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH)) | ||||
|  | ||||
| # Include the version info retrieved from curlver.h | ||||
| -include $(OBJDIR)/version.inc | ||||
|  | ||||
| # Global flags for all compilers | ||||
| CFLAGS	+= $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc | ||||
|  | ||||
| ifeq ($(CC),mwccnlm) | ||||
| LD	= mwldnlm | ||||
| LDFLAGS	= -nostdlib $< $(PRELUDE) $(LDLIBS) -o $@ -commandfile | ||||
| LIBEXT	= lib | ||||
| CFLAGS	+= -gccinc -inline off -opt nointrinsics -proc 586 | ||||
| CFLAGS	+= -relax_pointers | ||||
| #CFLAGS	+= -w on | ||||
| ifeq ($(LIBARCH),LIBC) | ||||
| ifeq ($(POSIXFL),1) | ||||
| 	PRELUDE = $(NDK_LIBC)/imports/posixpre.o | ||||
| else | ||||
| 	PRELUDE = $(NDK_LIBC)/imports/libcpre.o | ||||
| endif | ||||
| 	CFLAGS += -align 4 | ||||
| else | ||||
| 	# PRELUDE = $(NDK_CLIB)/imports/clibpre.o | ||||
| 	# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK | ||||
| 	PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj" | ||||
| 	# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h" | ||||
| 	CFLAGS += -align 1 | ||||
| endif | ||||
| else | ||||
| LD	= nlmconv | ||||
| LDFLAGS	= -T | ||||
| LIBEXT	= a | ||||
| CFLAGS	+= -m32 | ||||
| CFLAGS  += -fno-builtin -fno-strict-aliasing | ||||
| ifeq ($(findstring gcc,$(CC)),gcc) | ||||
| CFLAGS  += -fpcc-struct-return | ||||
| endif | ||||
| CFLAGS	+= -Wall # -pedantic | ||||
| ifeq ($(LIBARCH),LIBC) | ||||
| ifeq ($(POSIXFL),1) | ||||
| 	PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o | ||||
| else | ||||
| 	PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o | ||||
| endif | ||||
| else | ||||
| 	# PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o | ||||
| 	# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK | ||||
| 	# http://www.gknw.net/development/mk_nlm/gcc_pre.zip | ||||
| 	PRELUDE = $(NDK_ROOT)/pre/prelude.o | ||||
| 	CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h | ||||
| endif | ||||
| endif | ||||
|  | ||||
| NDK_ROOT = $(NDKBASE)/ndk | ||||
| ifndef NDK_CLIB | ||||
| NDK_CLIB = $(NDK_ROOT)/nwsdk | ||||
| endif | ||||
| ifndef NDK_LIBC | ||||
| NDK_LIBC = $(NDK_ROOT)/libc | ||||
| endif | ||||
| ifndef NDK_LDAP | ||||
| NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware | ||||
| endif | ||||
| CURL_INC = ../../include | ||||
| CURL_LIB = ../../lib | ||||
|  | ||||
| INCLUDES = -I$(CURL_INC) | ||||
|  | ||||
| ifeq ($(findstring -static,$(CFG)),-static) | ||||
| LINK_STATIC = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ares,$(CFG)),-ares) | ||||
| WITH_ARES = 1 | ||||
| endif | ||||
| ifeq ($(findstring -rtmp,$(CFG)),-rtmp) | ||||
| WITH_RTMP = 1 | ||||
| WITH_SSL = 1 | ||||
| WITH_ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ssh2,$(CFG)),-ssh2) | ||||
| WITH_SSH2 = 1 | ||||
| WITH_SSL = 1 | ||||
| WITH_ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -axtls,$(CFG)),-axtls) | ||||
| WITH_AXTLS = 1 | ||||
| WITH_SSL = | ||||
| else | ||||
| ifeq ($(findstring -ssl,$(CFG)),-ssl) | ||||
| WITH_SSL = 1 | ||||
| endif | ||||
| endif | ||||
| ifeq ($(findstring -zlib,$(CFG)),-zlib) | ||||
| WITH_ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -idn,$(CFG)),-idn) | ||||
| WITH_IDN = 1 | ||||
| endif | ||||
| ifeq ($(findstring -spnego,$(CFG)),-spnego) | ||||
| WITH_SPNEGO = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ipv6,$(CFG)),-ipv6) | ||||
| ENABLE_IPV6 = 1 | ||||
| endif | ||||
|  | ||||
| ifdef LINK_STATIC | ||||
| 	LDLIBS	= $(CURL_LIB)/libcurl.$(LIBEXT) | ||||
| ifdef WITH_ARES | ||||
| 	LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT) | ||||
| endif | ||||
| else | ||||
| 	MODULES	= libcurl.nlm | ||||
| 	IMPORTS	= @$(CURL_LIB)/libcurl.imp | ||||
| endif | ||||
| ifdef WITH_SSH2 | ||||
| 	# INCLUDES += -I$(LIBSSH2_PATH)/include | ||||
| ifdef LINK_STATIC | ||||
| 	LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT) | ||||
| else | ||||
| 	MODULES += libssh2.nlm | ||||
| 	IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp | ||||
| endif | ||||
| endif | ||||
| ifdef WITH_RTMP | ||||
| 	# INCLUDES += -I$(LIBRTMP_PATH) | ||||
| ifdef LINK_STATIC | ||||
| 	LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT) | ||||
| endif | ||||
| endif | ||||
| ifdef WITH_SSL | ||||
| 	INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) | ||||
| 	LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT) | ||||
| 	LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) | ||||
| 	IMPORTS += GetProcessSwitchCount RunningProcess | ||||
| ifdef WITH_SPNEGO | ||||
| 	# INCLUDES += -I$(FBOPENSSL_PATH)/include | ||||
| 	LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT) | ||||
| endif | ||||
| else | ||||
| ifdef WITH_AXTLS | ||||
| 	INCLUDES += -I$(AXTLS_PATH)/inc | ||||
| ifdef LINK_STATIC | ||||
| 	LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT) | ||||
| else | ||||
| 	MODULES += libaxtls.nlm | ||||
| 	IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp | ||||
| endif | ||||
| endif | ||||
| endif | ||||
| ifdef WITH_ZLIB | ||||
| 	# INCLUDES += -I$(ZLIB_PATH) | ||||
| ifdef LINK_STATIC | ||||
| 	LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT) | ||||
| else | ||||
| 	MODULES += libz.nlm | ||||
| 	IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp | ||||
| endif | ||||
| endif | ||||
| ifdef WITH_IDN | ||||
| 	# INCLUDES += -I$(LIBIDN_PATH)/include | ||||
| 	LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT) | ||||
| endif | ||||
|  | ||||
| ifeq ($(LIBARCH),LIBC) | ||||
| 	INCLUDES += -I$(NDK_LIBC)/include | ||||
| 	# INCLUDES += -I$(NDK_LIBC)/include/nks | ||||
| 	# INCLUDES += -I$(NDK_LIBC)/include/winsock | ||||
| 	CFLAGS += -D_POSIX_SOURCE | ||||
| else | ||||
| 	INCLUDES += -I$(NDK_CLIB)/include/nlm | ||||
| 	# INCLUDES += -I$(NDK_CLIB)/include | ||||
| endif | ||||
| ifndef DISABLE_LDAP | ||||
| 	# INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc | ||||
| endif | ||||
| CFLAGS	+= $(INCLUDES) | ||||
|  | ||||
| ifeq ($(MTSAFE),YES) | ||||
| 	XDCOPT = -n | ||||
| endif | ||||
| ifeq ($(MTSAFE),NO) | ||||
| 	XDCOPT = -u | ||||
| endif | ||||
| ifdef XDCOPT | ||||
| 	XDCDATA = $(OBJDIR)/$(TARGET).xdc | ||||
| endif | ||||
|  | ||||
| ifeq ($(findstring /sh,$(SHELL)),/sh) | ||||
| DL	= ' | ||||
| DS	= / | ||||
| PCT	= % | ||||
| #-include $(NDKBASE)/nlmconv/ncpfs.inc | ||||
| else | ||||
| DS	= \\ | ||||
| PCT	= %% | ||||
| endif | ||||
|  | ||||
| # Makefile.inc provides the CSOURCES and HHEADERS defines | ||||
| include Makefile.inc | ||||
|  | ||||
| check_PROGRAMS := $(patsubst %,%.nlm,$(strip $(check_PROGRAMS))) | ||||
|  | ||||
| .PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc | ||||
|  | ||||
|  | ||||
| all: prebuild $(check_PROGRAMS) | ||||
|  | ||||
| prebuild: $(OBJDIR) $(OBJDIR)/version.inc | ||||
|  | ||||
| $(OBJDIR)/%.o: %.c | ||||
| 	@echo Compiling $< | ||||
| 	$(CC) $(CFLAGS) -c $< -o $@ | ||||
|  | ||||
| $(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR) | ||||
| 	@echo Creating $@ | ||||
| 	@$(AWK) -f ../../packages/NetWare/get_ver.awk $< > $@ | ||||
|  | ||||
| install: $(INSTDIR) all | ||||
| 	@$(CP) $(check_PROGRAMS) $(INSTDIR) | ||||
|  | ||||
| clean: | ||||
| 	-$(RM) -r $(OBJDIR) | ||||
|  | ||||
| distclean vclean: clean | ||||
| 	-$(RM) $(check_PROGRAMS) | ||||
|  | ||||
| $(OBJDIR) $(INSTDIR): | ||||
| 	@$(MKDIR) $@ | ||||
|  | ||||
| %.nlm: $(OBJDIR)/%.o $(OBJDIR)/%.def $(XDCDATA) | ||||
| 	@echo Linking $@ | ||||
| 	@-$(RM) $@ | ||||
| 	@$(LD) $(LDFLAGS) $(OBJDIR)/$(@:.nlm=.def) | ||||
|  | ||||
| $(OBJDIR)/%.xdc: Makefile.netware | ||||
| 	@echo Creating $@ | ||||
| 	@$(MPKXDC) $(XDCOPT) $@ | ||||
|  | ||||
| $(OBJDIR)/%.def: Makefile.netware | ||||
| 	@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ | ||||
| 	@echo $(DL)# Do not edit this file - it is created by Make!$(DL) >> $@ | ||||
| 	@echo $(DL)# All your changes will be lost!!$(DL) >> $@ | ||||
| 	@echo $(DL)#$(DL) >> $@ | ||||
| 	@echo $(DL)copyright "$(COPYR)"$(DL) >> $@ | ||||
| 	@echo $(DL)description "$(DESCR) $(notdir $(@:.def=)) Example"$(DL) >> $@ | ||||
| 	@echo $(DL)version $(VERSION)$(DL) >> $@ | ||||
| ifdef NLMTYPE | ||||
| 	@echo $(DL)type $(NLMTYPE)$(DL) >> $@ | ||||
| endif | ||||
| ifdef STACK | ||||
| 	@echo $(DL)stack $(STACK)$(DL) >> $@ | ||||
| endif | ||||
| ifdef SCREEN | ||||
| 	@echo $(DL)screenname "$(DESCR) $(notdir $(@:.def=)) $(SCREEN)"$(DL) >> $@ | ||||
| else | ||||
| 	@echo $(DL)screenname "DEFAULT"$(DL) >> $@ | ||||
| endif | ||||
| ifneq ($(DB),NDEBUG) | ||||
| 	@echo $(DL)debug$(DL) >> $@ | ||||
| endif | ||||
| 	@echo $(DL)threadname "_$(notdir $(@:.def=))"$(DL) >> $@ | ||||
| ifdef XDCDATA | ||||
| 	@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ | ||||
| endif | ||||
| ifeq ($(LDRING),0) | ||||
| 	@echo $(DL)flag_on 16$(DL) >> $@ | ||||
| endif | ||||
| ifeq ($(LDRING),3) | ||||
| 	@echo $(DL)flag_on 512$(DL) >> $@ | ||||
| endif | ||||
| ifeq ($(LIBARCH),CLIB) | ||||
| 	@echo $(DL)start _Prelude$(DL) >> $@ | ||||
| 	@echo $(DL)exit _Stop$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@ | ||||
| 	@echo $(DL)module clib$(DL) >> $@ | ||||
| ifndef DISABLE_LDAP | ||||
| 	@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@ | ||||
| #	@echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@ | ||||
| 	@echo $(DL)module ldapsdk ldapssl$(DL) >> $@ | ||||
| endif | ||||
| else | ||||
| ifeq ($(POSIXFL),1) | ||||
| 	@echo $(DL)flag_on 4194304$(DL) >> $@ | ||||
| endif | ||||
| 	@echo $(DL)flag_on 64$(DL) >> $@ | ||||
| 	@echo $(DL)pseudopreemption$(DL) >> $@ | ||||
| ifeq ($(findstring posixpre,$(PRELUDE)),posixpre) | ||||
| 	@echo $(DL)start POSIX_Start$(DL) >> $@ | ||||
| 	@echo $(DL)exit POSIX_Stop$(DL) >> $@ | ||||
| 	@echo $(DL)check POSIX_CheckUnload$(DL) >> $@ | ||||
| else | ||||
| 	@echo $(DL)start _LibCPrelude$(DL) >> $@ | ||||
| 	@echo $(DL)exit _LibCPostlude$(DL) >> $@ | ||||
| 	@echo $(DL)check _LibCCheckUnload$(DL) >> $@ | ||||
| endif | ||||
| 	@echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@ | ||||
| 	@echo $(DL)module libc$(DL) >> $@ | ||||
| ifndef DISABLE_LDAP | ||||
| 	@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@ | ||||
| 	@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@ | ||||
| #	@echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@ | ||||
| 	@echo $(DL)module lldapsdk lldapssl$(DL) >> $@ | ||||
| endif | ||||
| endif | ||||
| ifdef MODULES | ||||
| 	@echo $(DL)module $(MODULES)$(DL) >> $@ | ||||
| endif | ||||
| ifdef EXPORTS | ||||
| 	@echo $(DL)export $(EXPORTS)$(DL) >> $@ | ||||
| endif | ||||
| ifdef IMPORTS | ||||
| 	@echo $(DL)import $(IMPORTS)$(DL) >> $@ | ||||
| endif | ||||
| ifeq ($(findstring nlmconv,$(LD)),nlmconv) | ||||
| 	@echo $(DL)input $(PRELUDE)$(DL) >> $@ | ||||
| 	@echo $(DL)input $(@:.def=.o)$(DL) >> $@ | ||||
| ifdef LDLIBS | ||||
| 	@echo $(DL)input $(LDLIBS)$(DL) >> $@ | ||||
| endif | ||||
| 	@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ | ||||
| endif | ||||
| @@ -55,6 +55,7 @@ htmltitle.cc   - download a HTML file and extract the <title> tag from a HTML | ||||
| http-post.c    - HTTP POST | ||||
| httpput.c      - HTTP PUT a local file | ||||
| https.c        - simple HTTPS transfer | ||||
| imap.c         - simple IMAP transfer | ||||
| multi-app.c    - a multi-interface app | ||||
| multi-debugcallback.c - a multi-interface app using the debug callback | ||||
| multi-double.c - a multi-interface app doing two simultaneous transfers | ||||
| @@ -63,6 +64,8 @@ multi-single.c - a multi-interface app getting a single file | ||||
| multithread.c  - an example using multi-treading transferring multiple files | ||||
| opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded | ||||
| persistant.c   - request two URLs with a persistent connection | ||||
| pop3s.c        - POP3S transfer | ||||
| pop3slist.c    - POP3S LIST | ||||
| post-callback.c - send a HTTP POST using a callback | ||||
| postit2.c      - send a HTTP multipart formpost | ||||
| sampleconv.c   - showing how a program on a non-ASCII platform would invoke | ||||
| @@ -73,4 +76,5 @@ simple.c       - the most simple download a URL source | ||||
| simplepost.c   - HTTP POST | ||||
| simplessl.c    - HTTPS example with certificates many options set | ||||
| synctime.c     - Sync local time by extracting date from remote HTTP servers | ||||
| url2file.c     - download a document and store it in a file | ||||
| 10-at-a-time.c - Download many files simultaneously, 10 at a time. | ||||
|   | ||||
| @@ -27,6 +27,7 @@ | ||||
| #  ifdef __VMS | ||||
|      typedef int intptr_t; | ||||
| #  endif | ||||
| #  include <stdint.h> | ||||
| #  include <unistd.h> | ||||
| #endif | ||||
| #include <sys/types.h> | ||||
| @@ -41,6 +42,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include <curl/curl.h> | ||||
| #include "printf_macro.h" | ||||
|  | ||||
| #if LIBCURL_VERSION_NUM < 0x070c03 | ||||
| #error "upgrade your libcurl to no less than 7.12.3" | ||||
| @@ -92,7 +94,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) | ||||
|  | ||||
|   retcode = read(fd, ptr, size * nmemb); | ||||
|  | ||||
|   fprintf(stderr, "*** We read %d bytes from file\n", retcode); | ||||
|   fprintf(stderr, "*** We read %" _FMT_SIZE_T " bytes from file\n", retcode); | ||||
|  | ||||
|   return retcode; | ||||
| } | ||||
|   | ||||
| @@ -239,8 +239,7 @@ static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) { | ||||
|   SSL_CTX_set_cipher_list(ctx,"RC4-MD5"); | ||||
|   SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); | ||||
|  | ||||
|   X509_STORE_add_cert(ctx->cert_store,sk_X509_value(p->ca, | ||||
|                                                     sk_X509_num(p->ca)-1)); | ||||
|   X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), sk_X509_value(p->ca, sk_X509_num(p->ca)-1)); | ||||
|  | ||||
|   SSL_CTX_set_verify_depth(ctx,2); | ||||
|  | ||||
|   | ||||
| @@ -28,13 +28,18 @@ | ||||
| #include <stdlib.h> | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
|  | ||||
| #include <sys/socket.h>       /*  socket definitions        */ | ||||
| #ifdef WIN32 | ||||
| #include <windows.h> | ||||
| #include <winsock2.h> | ||||
| #include <ws2tcpip.h> | ||||
| #define close closesocket | ||||
| #else | ||||
| #include <sys/types.h>        /*  socket types              */ | ||||
| #include <sys/socket.h>       /*  socket definitions        */ | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h>        /*  inet (3) funtions         */ | ||||
| #include <unistd.h>           /*  misc. UNIX functions      */ | ||||
| #endif | ||||
|  | ||||
| #include <errno.h> | ||||
|  | ||||
| @@ -72,6 +77,16 @@ int main(void) | ||||
|   struct sockaddr_in servaddr;  /*  socket address structure  */ | ||||
|   curl_socket_t sockfd; | ||||
|  | ||||
| #ifdef WIN32 | ||||
|   WSADATA wsaData; | ||||
|   int initwsa; | ||||
|  | ||||
|   if((initwsa = WSAStartup(MAKEWORD(2,0), &wsaData)) != 0) { | ||||
|     printf("WSAStartup failed: %d\n", initwsa); | ||||
|     return 1; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     /* | ||||
| @@ -82,7 +97,7 @@ int main(void) | ||||
|  | ||||
|     /* Create the socket "manually" */ | ||||
|     if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { | ||||
|       fprintf(stderr, "ECHOCLNT: Error creating listening socket.\n"); | ||||
|       printf("Error creating listening socket.\n"); | ||||
|       return 3; | ||||
|     } | ||||
|  | ||||
| @@ -90,7 +105,7 @@ int main(void) | ||||
|     servaddr.sin_family = AF_INET; | ||||
|     servaddr.sin_port   = htons(PORTNUM); | ||||
|  | ||||
|     if(inet_aton(IPADDR, &servaddr.sin_addr) <= 0 ) | ||||
|     if (INADDR_NONE == (servaddr.sin_addr.s_addr = inet_addr(IPADDR))) | ||||
|       return 2; | ||||
|  | ||||
|     if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) == | ||||
|   | ||||
| @@ -32,6 +32,7 @@ | ||||
| #else | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| #include "printf_macro.h" | ||||
|  | ||||
| /* | ||||
|  * This example shows an FTP upload, with a rename of the file just after | ||||
| @@ -56,7 +57,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) | ||||
|      by default internally */ | ||||
|   size_t retcode = fread(ptr, size, nmemb, stream); | ||||
|  | ||||
|   fprintf(stderr, "*** We read %d bytes from file\n", retcode); | ||||
|   fprintf(stderr, "*** We read %" _FMT_SIZE_T " bytes from file\n", retcode); | ||||
|   return retcode; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -39,7 +39,7 @@ | ||||
|  | ||||
| /* The MinGW headers are missing a few Win32 function definitions, | ||||
|    you shouldn't need this if you use VC++ */ | ||||
| #ifdef __MINGW32__ | ||||
| #if defined(__MINGW32__) && !defined(__MINGW64__) | ||||
| int __cdecl _snscanf(const char * input, size_t length, const char * format, ...); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include <curl/curl.h> | ||||
| #include "printf_macro.h" | ||||
|  | ||||
| /* | ||||
|  * This example shows a HTTP PUT operation. PUTs a file given as a command | ||||
| @@ -45,7 +46,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) | ||||
|      by default internally */ | ||||
|   retcode = fread(ptr, size, nmemb, stream); | ||||
|  | ||||
|   fprintf(stderr, "*** We read %d bytes from file\n", retcode); | ||||
|   fprintf(stderr, "*** We read %" _FMT_SIZE_T " bytes from file\n", retcode); | ||||
|  | ||||
|   return retcode; | ||||
| } | ||||
|   | ||||
							
								
								
									
										44
									
								
								docs/examples/imap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								docs/examples/imap.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
|  * are also available at http://curl.haxx.se/docs/copyright.html. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the COPYING file. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| #include <stdio.h> | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   CURL *curl; | ||||
|   CURLcode res; | ||||
|  | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     /* Set username and password */ | ||||
|     curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); | ||||
|  | ||||
|     /* This will fetch the mailbox named "foobar" */ | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/foobar"); | ||||
|  | ||||
|     res = curl_easy_perform(curl); | ||||
|  | ||||
|     /* always cleanup */ | ||||
|     curl_easy_cleanup(curl); | ||||
|   } | ||||
|   return (int)res; | ||||
| } | ||||
							
								
								
									
										68
									
								
								docs/examples/pop3s.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								docs/examples/pop3s.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
|  * are also available at http://curl.haxx.se/docs/copyright.html. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the COPYING file. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| #include <stdio.h> | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   CURL *curl; | ||||
|   CURLcode res; | ||||
|  | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     /* Set username and password */ | ||||
|     curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); | ||||
|  | ||||
|     /* This will only fetch the message with ID "1" of the given mailbox */ | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/1"); | ||||
|  | ||||
| #ifdef SKIP_PEER_VERIFICATION | ||||
|     /* | ||||
|      * If you want to connect to a site who isn't using a certificate that is | ||||
|      * signed by one of the certs in the CA bundle you have, you can skip the | ||||
|      * verification of the server's certificate. This makes the connection | ||||
|      * A LOT LESS SECURE. | ||||
|      * | ||||
|      * If you have a CA cert for the server stored someplace else than in the | ||||
|      * default bundle, then the CURLOPT_CAPATH option might come handy for | ||||
|      * you. | ||||
|      */ | ||||
|     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | ||||
| #endif | ||||
|  | ||||
| #ifdef SKIP_HOSTNAME_VERFICATION | ||||
|     /* | ||||
|      * If the site you're connecting to uses a different host name that what | ||||
|      * they have mentioned in their server certificate's commonName (or | ||||
|      * subjectAltName) fields, libcurl will refuse to connect. You can skip | ||||
|      * this check, but this will make the connection less secure. | ||||
|      */ | ||||
|     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | ||||
| #endif | ||||
|  | ||||
|     res = curl_easy_perform(curl); | ||||
|  | ||||
|     /* always cleanup */ | ||||
|     curl_easy_cleanup(curl); | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										68
									
								
								docs/examples/pop3slist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								docs/examples/pop3slist.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
|  * are also available at http://curl.haxx.se/docs/copyright.html. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the COPYING file. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| #include <stdio.h> | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   CURL *curl; | ||||
|   CURLcode res; | ||||
|  | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     /* Set username and password */ | ||||
|     curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); | ||||
|  | ||||
|     /* This will list every message of the given mailbox */ | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/"); | ||||
|  | ||||
| #ifdef SKIP_PEER_VERIFICATION | ||||
|     /* | ||||
|      * If you want to connect to a site who isn't using a certificate that is | ||||
|      * signed by one of the certs in the CA bundle you have, you can skip the | ||||
|      * verification of the server's certificate. This makes the connection | ||||
|      * A LOT LESS SECURE. | ||||
|      * | ||||
|      * If you have a CA cert for the server stored someplace else than in the | ||||
|      * default bundle, then the CURLOPT_CAPATH option might come handy for | ||||
|      * you. | ||||
|      */ | ||||
|     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | ||||
| #endif | ||||
|  | ||||
| #ifdef SKIP_HOSTNAME_VERFICATION | ||||
|     /* | ||||
|      * If the site you're connecting to uses a different host name that what | ||||
|      * they have mentioned in their server certificate's commonName (or | ||||
|      * subjectAltName) fields, libcurl will refuse to connect. You can skip | ||||
|      * this check, but this will make the connection less secure. | ||||
|      */ | ||||
|     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | ||||
| #endif | ||||
|  | ||||
|     res = curl_easy_perform(curl); | ||||
|  | ||||
|     /* always cleanup */ | ||||
|     curl_easy_cleanup(curl); | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										45
									
								
								docs/examples/printf_macro.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								docs/examples/printf_macro.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
|  * are also available at http://curl.haxx.se/docs/copyright.html. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the COPYING file. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| /* Simple hack trying to get a valid printf format string for size_t. | ||||
|  * If that fails for your platform you can define your own _FMT_SIZE_T, | ||||
|  * f.e.: -D_FMT_SIZE_T="zd" | ||||
|  */ | ||||
| #ifndef _PRINTF_MACRO_H | ||||
| #define _PRINTF_MACRO_H | ||||
|  | ||||
| #ifndef _FMT_SIZE_T | ||||
| #ifdef WIN32 | ||||
| #define _FMT_SIZE_T "Id" | ||||
| #else | ||||
| /* | ||||
| "zd" is a GNU extension to POSIX; so we dont use it for size_t but hack around | ||||
| #define _FMT_SIZE_T "zd" | ||||
| */ | ||||
| #ifdef __x86_64__ | ||||
| #define _FMT_SIZE_T "lu" | ||||
| #else | ||||
| #define _FMT_SIZE_T "u" | ||||
| #endif /* __x86_64__ */ | ||||
| #endif /* WIN32 */ | ||||
| #endif /* !_FMT_SIZE_T */ | ||||
|  | ||||
| #endif /* !_PRINTF_MACRO_H */ | ||||
							
								
								
									
										84
									
								
								docs/examples/progressfunc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								docs/examples/progressfunc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
|  * are also available at http://curl.haxx.se/docs/copyright.html. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the COPYING file. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| #include <stdio.h> | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| #define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES         6000 | ||||
| #define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL     3 | ||||
|  | ||||
| struct myprogress { | ||||
|   double lastruntime; | ||||
|   CURL *curl; | ||||
| }; | ||||
|  | ||||
| static int progress(void *p, | ||||
|                     double dltotal, double dlnow, | ||||
|                     double ultotal, double ulnow) | ||||
| { | ||||
|   struct myprogress *myp = (struct myprogress *)p; | ||||
|   CURL *curl = myp->curl; | ||||
|   double curtime = 0; | ||||
|  | ||||
|   curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime); | ||||
|  | ||||
|   /* under certain circumstances it may be desirable for certain functionality | ||||
|      to only run every N seconds, in order to do this the transaction time can | ||||
|      be used */ | ||||
|   if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) { | ||||
|     myp->lastruntime = curtime; | ||||
|     fprintf(stderr, "TOTAL TIME: %f \r\n", curtime); | ||||
|   } | ||||
|  | ||||
|   fprintf(stderr, "UP: %g of %g  DOWN: %g of %g\r\n", | ||||
|           ulnow, ultotal, dlnow, dltotal); | ||||
|  | ||||
|   if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES) | ||||
|     return 1; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   CURL *curl; | ||||
|   CURLcode res=0; | ||||
|   struct myprogress prog; | ||||
|  | ||||
|   curl = curl_easy_init(); | ||||
|   if(curl) { | ||||
|     prog.lastruntime = 0; | ||||
|     prog.curl = curl; | ||||
|  | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/"); | ||||
|     curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress); | ||||
|     /* pass the struct pointer into the progress function */ | ||||
|     curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog); | ||||
|     curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); | ||||
|     res = curl_easy_perform(curl); | ||||
|  | ||||
|     if(res) | ||||
|       fprintf(stderr, "%s\n", curl_easy_strerror(res)); | ||||
|  | ||||
|     /* always cleanup */ | ||||
|     curl_easy_cleanup(curl); | ||||
|   } | ||||
|   return (int)res; | ||||
| } | ||||
| @@ -73,7 +73,7 @@ static void rtsp_options(CURL *curl, const char *uri) | ||||
|   CURLcode res = CURLE_OK; | ||||
|   printf("\nRTSP: OPTIONS %s\n", uri); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS); | ||||
|   my_curl_easy_perform(curl); | ||||
| } | ||||
|  | ||||
| @@ -93,7 +93,7 @@ static void rtsp_describe(CURL *curl, const char *uri, | ||||
|     printf("Writing SDP to '%s'\n", sdp_filename); | ||||
|   } | ||||
|   my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE); | ||||
|   my_curl_easy_perform(curl); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); | ||||
|   if (sdp_fp != stdout) { | ||||
| @@ -109,7 +109,7 @@ static void rtsp_setup(CURL *curl, const char *uri, const char *transport) | ||||
|   printf("      TRANSPORT %s\n", transport); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP); | ||||
|   my_curl_easy_perform(curl); | ||||
| } | ||||
|  | ||||
| @@ -121,7 +121,7 @@ static void rtsp_play(CURL *curl, const char *uri, const char *range) | ||||
|   printf("\nRTSP: PLAY %s\n", uri); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RANGE, range); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY); | ||||
|   my_curl_easy_perform(curl); | ||||
| } | ||||
|  | ||||
| @@ -131,7 +131,7 @@ static void rtsp_teardown(CURL *curl, const char *uri) | ||||
| { | ||||
|   CURLcode res = CURLE_OK; | ||||
|   printf("\nRTSP: TEARDOWN %s\n", uri); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_TEARDOWN); | ||||
|   my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN); | ||||
|   my_curl_easy_perform(curl); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <curl/curl.h> | ||||
| #include "printf_macro.h" | ||||
|  | ||||
| /* Auxiliary function that waits on the socket. */ | ||||
| static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms) | ||||
| @@ -122,7 +123,7 @@ int main(void) | ||||
|       if(CURLE_OK != res) | ||||
|         break; | ||||
|  | ||||
|       printf("Received %u bytes.\n", iolen); | ||||
|       printf("Received %" _FMT_SIZE_T " bytes.\n", iolen); | ||||
|     } | ||||
|  | ||||
|     /* always cleanup */ | ||||
|   | ||||
| @@ -123,13 +123,13 @@ int main(void) | ||||
|    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); | ||||
|    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM); | ||||
|    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list); | ||||
|    curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); | ||||
|    curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | ||||
|    curl_easy_setopt(curl, CURLOPT_READDATA, &pooh); | ||||
|    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0); | ||||
|    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0L); | ||||
|    curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L); | ||||
|    curl_multi_add_handle(mcurl, curl); | ||||
|  | ||||
|    mp_timedout = 0; | ||||
|   | ||||
| @@ -94,13 +94,13 @@ int main(void) | ||||
|      * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer | ||||
|      * will continue anyway - see the security discussion in the libcurl | ||||
|      * tutorial for more details. */ | ||||
|     curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); | ||||
|     curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); | ||||
|  | ||||
|     /* If your server doesn't have a valid certificate, then you can disable | ||||
|      * part of the Transport Layer Security protection by setting the | ||||
|      * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false). | ||||
|      *   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); | ||||
|      *   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); | ||||
|      *   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | ||||
|      *   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | ||||
|      * That is, in general, a bad idea. It is still better than sending your | ||||
|      * authentication details in plain text though. | ||||
|      * Instead, you should get the issuer certificate (or the host certificate | ||||
| @@ -135,7 +135,7 @@ int main(void) | ||||
|     /* Since the traffic will be encrypted, it is very useful to turn on debug | ||||
|      * information within libcurl to see what is happening during the transfer. | ||||
|      */ | ||||
|     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); | ||||
|     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); | ||||
|  | ||||
|     /* send the message (including headers) */ | ||||
|     res = curl_easy_perform(curl); | ||||
|   | ||||
| @@ -147,7 +147,7 @@ size_t SyncTime_CURL_WriteHeader(void *ptr, size_t size, size_t nmemb, | ||||
|                                          TmpStr1 & 2? */ | ||||
|         AutoSyncTime = 0; | ||||
|       else { | ||||
|         RetVal = sscanf ((char *)(ptr), "Date: %s %d %s %d %d:%d:%d", | ||||
|         RetVal = sscanf ((char *)(ptr), "Date: %s %hu %s %hu %hu:%hu:%hu", | ||||
|                          TmpStr1, &SYSTime.wDay, TmpStr2, &SYSTime.wYear, | ||||
|                          &SYSTime.wHour, &SYSTime.wMinute, &SYSTime.wSecond); | ||||
|  | ||||
|   | ||||
							
								
								
									
										81
									
								
								docs/examples/url2file.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								docs/examples/url2file.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
|  * are also available at http://curl.haxx.se/docs/copyright.html. | ||||
|  * | ||||
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
|  * copies of the Software, and permit persons to whom the Software is | ||||
|  * furnished to do so, under the terms of the COPYING file. | ||||
|  * | ||||
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
|  * KIND, either express or implied. | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) | ||||
| { | ||||
|   size_t written = fwrite(ptr, size, nmemb, (FILE *)stream); | ||||
|   return written; | ||||
| } | ||||
|  | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
|   CURL *curl_handle; | ||||
|   static const char *pagefilename = "page.out"; | ||||
|   FILE *pagefile; | ||||
|  | ||||
|   if(argc < 2 ) { | ||||
|     printf("Usage: %s <URL>\n", argv[0]); | ||||
|     return 1; | ||||
|   } | ||||
|  | ||||
|   curl_global_init(CURL_GLOBAL_ALL); | ||||
|  | ||||
|   /* init the curl session */ | ||||
|   curl_handle = curl_easy_init(); | ||||
|  | ||||
|   /* set URL to get here */ | ||||
|   curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]); | ||||
|  | ||||
|   /* Switch on full protocol/debug output while testing */ | ||||
|   curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); | ||||
|  | ||||
|   /* disable progress meter, set to 0L to enable and disable debug output */ | ||||
|   curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L); | ||||
|  | ||||
|   /* send all data to this function  */ | ||||
|   curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data); | ||||
|  | ||||
|   /* open the file */ | ||||
|   pagefile = fopen(pagefilename, "wb"); | ||||
|   if (pagefile) { | ||||
|  | ||||
|     /* write the page body to this file handle. CURLOPT_FILE is also known as | ||||
|        CURLOPT_WRITEDATA*/ | ||||
|     curl_easy_setopt(curl_handle, CURLOPT_FILE, pagefile); | ||||
|  | ||||
|     /* get it! */ | ||||
|     curl_easy_perform(curl_handle); | ||||
|  | ||||
|     /* close the header file */ | ||||
|     fclose(pagefile); | ||||
|   } | ||||
|  | ||||
|   /* cleanup curl stuff */ | ||||
|   curl_easy_cleanup(curl_handle); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| @@ -82,7 +82,7 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf			 \ | ||||
| CLEANFILES = $(HTMLPAGES) $(PDFPAGES) | ||||
|  | ||||
| EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \ | ||||
|   symbols-in-versions | ||||
|   symbols-in-versions symbols.pl | ||||
| MAN2HTML= roffit --mandir=. < $< >$@ | ||||
|  | ||||
| SUFFIXES = .3 .html | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| .\" *                            | (__| |_| |  _ <| |___ | ||||
| .\" *                             \___|\___/|_| \_\_____| | ||||
| .\" * | ||||
| .\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * | ||||
| .\" * This software is licensed as described in the file COPYING, which | ||||
| .\" * you should have received as part of this distribution. The terms | ||||
| @@ -171,8 +171,12 @@ Set the \fIuserdata\fP argument with the \fICURLOPT_WRITEDATA\fP option. | ||||
|  | ||||
| The callback function will be passed as much data as possible in all invokes, | ||||
| but you cannot possibly make any assumptions. It may be one byte, it may be | ||||
| thousands. 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. | ||||
| thousands. The maximum amount of body data that can be passed to the write | ||||
| callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE (the usual | ||||
| default is 16K). If you however have \fICURLOPT_HEADER\fP set, which sends | ||||
| header data to the write callback, you can get up to | ||||
| \fICURL_MAX_HTTP_HEADER\fP bytes of header data passed into it. This usually | ||||
| means 100K. | ||||
| .IP CURLOPT_WRITEDATA | ||||
| Data pointer to pass to the file write function. If you use the | ||||
| \fICURLOPT_WRITEFUNCTION\fP option, this is the pointer you'll get as | ||||
| @@ -290,10 +294,9 @@ argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP. | ||||
| Function pointer that should match the \fIcurl_opensocket_callback\fP | ||||
| prototype found in \fI<curl/curl.h>\fP. This function gets called by libcurl | ||||
| instead of the \fIsocket(2)\fP call. The callback's \fIpurpose\fP argument | ||||
| identifies the exact purpose for this particular socket, and currently only | ||||
| one value is supported: \fICURLSOCKTYPE_IPCXN\fP for the primary connection | ||||
| (meaning the control connection in the FTP case). Future versions of libcurl | ||||
| may support more purposes. It passes the resolved peer address as a | ||||
| identifies the exact purpose for this particular socket: | ||||
| \fICURLSOCKTYPE_IPCXN\fP is for IP based connections. Future versions of | ||||
| libcurl may support more purposes. It passes the resolved peer address as a | ||||
| \fIaddress\fP argument so the callback can modify the address or refuse to | ||||
| connect at all. The callback function should return the socket or | ||||
| \fICURL_SOCKET_BAD\fP in case no connection should be established or any error | ||||
| @@ -354,6 +357,9 @@ of bytes actually taken care of. If that amount differs from the amount passed | ||||
| to your function, it'll signal an error to the library. This will abort the | ||||
| transfer and return \fICURL_WRITE_ERROR\fP. | ||||
|  | ||||
| A complete header that is passed to this function can be up to | ||||
| \fICURL_MAX_HTTP_HEADER\fP (100K) bytes. | ||||
|  | ||||
| If this option is not set, or if it is set to NULL, but | ||||
| \fICURLOPT_HEADERDATA\fP (\fICURLOPT_WRITEHEADER\fP) is set to anything but | ||||
| NULL, the function used to accept response data will be used instead. That is, | ||||
| @@ -584,20 +590,162 @@ POST/PUT and a 401 or 407 is received immediately afterwards. | ||||
| .SH NETWORK OPTIONS | ||||
| .IP CURLOPT_URL | ||||
| The actual URL to deal with. The parameter should be a char * to a zero | ||||
| terminated string. | ||||
| terminated string which must be URL-encoded in the following format: | ||||
|  | ||||
| If the given URL lacks the protocol part ("http://" or "ftp://" etc), it will | ||||
| attempt to guess which protocol to use based on the given host name. If the | ||||
| given protocol of the set URL is not supported, libcurl will return on error | ||||
| (\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP or | ||||
| \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info | ||||
| on which protocols are supported. | ||||
| scheme://host:port/path | ||||
|  | ||||
| The string given to CURLOPT_URL must be url-encoded and follow RFC 2396 | ||||
| (http://curl.haxx.se/rfc/rfc2396.txt). | ||||
| For a greater explanation of the format please see RFC 3986 | ||||
| (http://curl.haxx.se/rfc/rfc3986.txt). | ||||
|  | ||||
| Starting with version 7.20.0, the fragment part of the URI will not be send as | ||||
| part of the path, which was the case previously. | ||||
| If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://" | ||||
| etc), libcurl will attempt to resolve which protocol to use based on the | ||||
| given host mame. If the protocol is not supported, libcurl will return | ||||
| (\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP | ||||
| or \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed | ||||
| information on which protocols are supported. | ||||
|  | ||||
| The host part of the URL contains the address of the server that you want to | ||||
| connect to. This can be the fully qualified domain name of the server, the | ||||
| local network name of the machine on your network or the IP address of the | ||||
| server or machine represented by either an IPv4 or IPv6 address. For example: | ||||
|  | ||||
| http://www.example.com/ | ||||
|  | ||||
| http://hostname/ | ||||
|  | ||||
| http://192.168.0.1/ | ||||
|  | ||||
| http://[2001:1890:1112:1::20]/ | ||||
|  | ||||
| It is also possible to specify the user name and password as part of the | ||||
| host, for some protocols, when connecting to servers that require | ||||
| authentication. | ||||
|  | ||||
| For example the following types of authentication support this: | ||||
|  | ||||
| http://user:password@www.domain.com | ||||
| ftp://user:password@ftp.domain.com | ||||
| pop3://user:password@mail.domain.com | ||||
|  | ||||
| The port is optional and when not specified libcurl will use the default port | ||||
| based on the determined or specified protocol: 80 for http, 21 for ftp and 25 | ||||
| for smtp, etc. The following examples show how to specify the port: | ||||
|  | ||||
| http://www.weirdserver.com:8080/ - This will connect to a web server using | ||||
| port 8080. | ||||
|  | ||||
| smtp://mail.domain.com:587/ - This will connect to a smtp server on the | ||||
| alternative mail port. | ||||
|  | ||||
| The path part of the URL is protocol specific and whilst some examples are | ||||
| given below this list is not conclusive: | ||||
|  | ||||
| .B HTTP | ||||
|  | ||||
| The path part of a HTTP request specifies the file to retrieve and from what | ||||
| directory. If the directory is not specified then the web server's root | ||||
| directory is used. If the file is omitted then the default document will be | ||||
| retrieved for either the directory specified or the root directory. The | ||||
| exact resource returned for each URL is entirely dependent on the server's | ||||
| configuration. | ||||
|  | ||||
| http://www.netscape.com - This gets the main page (index.html in this | ||||
| example) from Netscape's web server. | ||||
|  | ||||
| http://www.netscape.com/index.html - This returns the main page from Netscape | ||||
| by specifying the page to get. | ||||
|  | ||||
| http://www.netscape.com/contactus/ - This returns the default document from | ||||
| the contactus directory. | ||||
|  | ||||
| .B FTP | ||||
|  | ||||
| The path part of an FTP request specifies the file to retrieve and from what | ||||
| directory. If the file part is omitted then libcurl downloads the directory | ||||
| listing for the directory specified. If the directory is omitted then | ||||
| the directory listing for the root / home directory will be returned. | ||||
|  | ||||
| ftp://cool.haxx.se - This retrieves the directory listing for our FTP server. | ||||
|  | ||||
| ftp://cool.haxx.se/readme.txt - This downloads the file readme.txt from the | ||||
| root directory. | ||||
|  | ||||
| ftp://cool.haxx.se/libcurl/readme.txt - This downloads readme.txt from the | ||||
| libcurl directory. | ||||
|  | ||||
| ftp://user:password@my.example.com/readme.txt - This retrieves the readme.txt | ||||
| file from the user's home directory. When a username and password is | ||||
| specified, everything that is specified in the path part is relative to the | ||||
| user's home directory. To retrieve files from the root directory or a | ||||
| directory underneath the root directory then the absolute path must be | ||||
| specified by prepending an additional forward slash to the beginning of the | ||||
| path. | ||||
|  | ||||
| ftp://user:password@my.example.com//readme.txt - This retrieves the readme.txt | ||||
| from the root directory when logging in as a specified user. | ||||
|  | ||||
| .B SMTP | ||||
|  | ||||
| The path part of a SMTP request specifies the host name to present during | ||||
| communication with the mail server. If the path is omitted then libcurl will | ||||
| attempt to resolve the local computer's host name. However, this may not | ||||
| return the fully qualified domain name that is required by some mail servers | ||||
| and specifying this path allows you to set an alternative name, such as | ||||
| your machine's fully qualified domain name, which you might have obtained | ||||
| from an external function such as gethostname or getaddrinfo. | ||||
|  | ||||
| smtp://mail.domain.com - This connects to the mail server at domain.com and | ||||
| sends your local computer's host name in the HELO / EHLO command. | ||||
|  | ||||
| smtp://mail.domain.com/client.domain.com - This will send client.domain.com in | ||||
| the HELO / EHLO command to the mail server at domain.com. | ||||
|  | ||||
| .B POP3 | ||||
|  | ||||
| The path part of a POP3 request specifies the mailbox (message) to retrieve. | ||||
| If the mailbox is not specified then a list of waiting messages is returned | ||||
| instead. | ||||
|  | ||||
| pop3://user:password@mail.domain.com - This lists the available messages | ||||
| pop3://user:password@mail.domain.com/1 - This retrieves the first message | ||||
|  | ||||
| .B SCP | ||||
|  | ||||
| The path part of an SCP request specifies the file to retrieve and from what | ||||
| directory. The file part may not be omitted. The file is taken as an absolute | ||||
| path from the root directory on the server. To specify a path relative to | ||||
| the user's home directory on the server, prepend ~/ to the path portion. | ||||
| If the user name is not embedded in the URL, it can be set with the | ||||
| \fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option. | ||||
|  | ||||
| scp://user@example.com/etc/issue - This specifies the file /etc/issue | ||||
|  | ||||
| scp://example.com/~/my-file - This specifies the file my-file in the | ||||
| user's home directory on the server | ||||
|  | ||||
| .B SFTP | ||||
|  | ||||
| The path part of an SFTP request specifies the file to retrieve and from what | ||||
| directory. If the file part is omitted then libcurl downloads the directory | ||||
| listing for the directory specified.  If the path ends in a / then a directory | ||||
| listing is returned instead of a file.  If the path is omitted entirely then | ||||
| the directory listing for the root / home directory will be returned. | ||||
| If the user name is not embedded in the URL, it can be set with the | ||||
| \fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option. | ||||
|  | ||||
| sftp://user:password@example.com/etc/issue - This specifies the file | ||||
| /etc/issue | ||||
|  | ||||
| sftp://user@example.com/~/my-file - This specifies the file my-file in the | ||||
| user's home directory | ||||
|  | ||||
| sftp://ssh.example.com/~/Documents/ - This requests a directory listing | ||||
| of the Documents directory under the user's home directory | ||||
|  | ||||
| .B NOTES | ||||
|  | ||||
| Starting with version 7.20.0, the fragment part of the URI will not be sent as | ||||
| part of the path, which was previously the case. | ||||
|  | ||||
| \fICURLOPT_URL\fP is the only option that \fBmust\fP be set before | ||||
| \fIcurl_easy_perform(3)\fP is called. | ||||
| @@ -666,10 +814,10 @@ this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_HTTP_1_0\fP (added in 7.19.4), | ||||
|  | ||||
| If you set \fBCURLOPT_PROXYTYPE\fP to \fICURLPROXY_HTTP_1_0\fP, it will only | ||||
| affect how libcurl speaks to a proxy when CONNECT is used. The HTTP version | ||||
| used for "regular" HTTP requests is instead controled with | ||||
| used for "regular" HTTP requests is instead controlled with | ||||
| \fICURLOPT_HTTP_VERSION\fP. | ||||
| .IP CURLOPT_NOPROXY | ||||
| Pass a pointer to a zero terminated string. The should be a comma- separated | ||||
| Pass a pointer to a zero terminated string. The should be a comma separated | ||||
| list of hosts which do not use a proxy, if one is specified.  The only | ||||
| wildcard is a single * character, which matches all hosts, and effectively | ||||
| disables the proxy. Each name in this list is matched as either a domain which | ||||
| @@ -695,6 +843,15 @@ negotiation. (Added in 7.19.4). | ||||
| Pass a char * as parameter. This sets the interface name to use as outgoing | ||||
| network interface. The name can be an interface name, an IP address, or a host | ||||
| name. | ||||
|  | ||||
| Starting with 7.24.0: If the parameter starts with "if!" then it is treated as | ||||
| only as interface name and no attempt will ever be named to do treat it as an | ||||
| IP address or to do name resolution on it.  If the parameter starts with | ||||
| \&"host!" it is treated as either an IP address or a hostname.  Hostnames are | ||||
| resolved synchronously.  Using the if! format is highly recommended when using | ||||
| the multi interfaces to avoid allowing the code to block.  If "if!" is | ||||
| specified but the parameter does not match an existing interface, | ||||
| CURLE_INTERFACE_FAILED is returned. | ||||
| .IP CURLOPT_LOCALPORT | ||||
| Pass a long. This sets the local port number of the socket used for | ||||
| connection. This can be used in combination with \fICURLOPT_INTERFACE\fP and | ||||
| @@ -933,12 +1090,12 @@ You need to build libcurl with GnuTLS or OpenSSL with TLS-SRP support for this | ||||
| to work. (Added in 7.21.4) | ||||
| .RE | ||||
| .IP CURLOPT_TLSAUTH_USERNAME | ||||
| Pass a char * as parameter, which should point to the zero-terminated username | ||||
| Pass a char * as parameter, which should point to the zero terminated username | ||||
| to use for the TLS authentication method specified with the | ||||
| \fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the | ||||
| \fICURLOPT_TLS_PASSWORD\fP option also be set. (Added in 7.21.4) | ||||
| .IP CURLOPT_TLSAUTH_PASSWORD | ||||
| Pass a char * as parameter, which should point to the zero-terminated password | ||||
| Pass a char * as parameter, which should point to the zero terminated password | ||||
| to use for the TLS authentication method specified with the | ||||
| \fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the | ||||
| \fICURLOPT_TLS_USERNAME\fP option also be set. (Added in 7.21.4) | ||||
| @@ -1188,7 +1345,7 @@ option and thus you need to concatenate them all in one single string. Set | ||||
| multiple cookies in one string like this: "name1=content1; name2=content2;" | ||||
| etc. | ||||
|  | ||||
| This option sets the cookie header explictly in the outgoing request(s). If | ||||
| This option sets the cookie header explicitly in the outgoing request(s). If | ||||
| multiple requests are done due to authentication, followed redirections or | ||||
| similar, they will all get this cookie passed on. | ||||
|  | ||||
| @@ -1336,9 +1493,9 @@ fully valid list of 'struct curl_slist' structs properly filled in with text | ||||
| strings. Use \fIcurl_slist_append(3)\fP to append strings (commands) to the | ||||
| list, and clear the entire list afterwards with | ||||
| \fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a NULL | ||||
| to this option. When speaking to a FTP server, prefix the command with an | ||||
| asterisk (*) to make libcurl continue even if the command fails as by default | ||||
| libcurl will stop at first failure. | ||||
| to this option. When speaking to a FTP (or SFTP since 7.24.0) server, prefix | ||||
| the command with an asterisk (*) to make libcurl continue even if the command | ||||
| fails as by default libcurl will stop at first failure. | ||||
|  | ||||
| The set of valid FTP commands depends on the server (see RFC959 for a list of | ||||
| mandatory commands). | ||||
| @@ -1471,7 +1628,7 @@ a reply. | ||||
| Initiate the shutdown and wait for a reply. | ||||
| .RE | ||||
| .IP CURLOPT_FTP_ACCOUNT | ||||
| Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP | ||||
| Pass a pointer to a zero terminated string (or NULL to disable). When an FTP | ||||
| server asks for "account data" after user name and password has been provided, | ||||
| this data is sent off using the ACCT command. (Added in 7.13.0) | ||||
| .IP CURLOPT_FTP_FILEMETHOD | ||||
| @@ -1693,6 +1850,9 @@ as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP. | ||||
| For uploading using SCP, this option or \fICURLOPT_INFILESIZE_LARGE\fP is | ||||
| mandatory. | ||||
|  | ||||
| When sending emails using SMTP, this command can be used to specify the | ||||
| optional SIZE parameter for the MAIL FROM command. (Added in 7.23.0) | ||||
|  | ||||
| This option does not limit how much data libcurl will actually send, as that | ||||
| is controlled entirely by what the read callback returns. | ||||
| .IP CURLOPT_INFILESIZE_LARGE | ||||
| @@ -1822,9 +1982,9 @@ re-use (default behavior). | ||||
| .IP CURLOPT_CONNECTTIMEOUT | ||||
| Pass a long. It should contain the maximum time in seconds that you allow the | ||||
| connection to the server to take.  This only limits the connection phase, once | ||||
| it has connected, this option is of no more use. Set to zero to disable | ||||
| connection timeout (it will then only timeout on the system's internal | ||||
| timeouts). See also the \fICURLOPT_TIMEOUT\fP option. | ||||
| it has connected, this option is of no more use. Set to zero to switch to the | ||||
| default built-in connection timeout - 300 seconds. See also the | ||||
| \fICURLOPT_TIMEOUT\fP option. | ||||
|  | ||||
| In unix-like systems, this might cause signals to be used unless | ||||
| \fICURLOPT_NOSIGNAL\fP is set. | ||||
| @@ -1896,6 +2056,24 @@ resolves, by including a string in the linked list that uses the format | ||||
| and port number must exactly match what was already added previously. | ||||
|  | ||||
| (Added in 7.21.3) | ||||
| .IP CURLOPT_DNS_SERVERS | ||||
| Set the list of DNS servers to be used instead of the system default. | ||||
| The format of the dns servers option is: | ||||
|  | ||||
| host[:port][,host[:port]]... | ||||
|  | ||||
| For example: | ||||
|  | ||||
| 192.168.1.100,192.168.1.101,3.4.5.6 | ||||
|  | ||||
| This option requires that libcurl was built with a resolver backend that | ||||
| supports this operation. The c-ares backend is the only such one. | ||||
|  | ||||
| (Added in 7.24.0) | ||||
| .IP CURLOPT_ACCEPTTIMEOUT_MS | ||||
| Pass a long telling libcurl the maximum number of milliseconds to wait for a | ||||
| server to connect back to libcurl when an active FTP connection is used. If no | ||||
| timeout is set, the internal default of 60000 will be used. (Added in 7.24.0) | ||||
| .SH SSL and SECURITY OPTIONS | ||||
| .IP CURLOPT_SSLCERT | ||||
| Pass a pointer to a zero terminated string as parameter. The string should be | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| .\" *                            | (__| |_| |  _ <| |___ | ||||
| .\" *                             \___|\___/|_| \_\_____| | ||||
| .\" * | ||||
| .\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * | ||||
| .\" * This software is licensed as described in the file COPYING, which | ||||
| .\" * you should have received as part of this distribution. The terms | ||||
| @@ -23,9 +23,9 @@ | ||||
| .SH NAME | ||||
| curl_easy_strerror - return string describing error code | ||||
| .SH SYNOPSIS | ||||
| .nf | ||||
| .B #include <curl/curl.h> | ||||
| .BI "const char *curl_easy_strerror(CURLcode " errornum ");" | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| const char *curl_easy_strerror(CURLcode errornum); | ||||
| .SH DESCRIPTION | ||||
| The curl_easy_strerror() function returns a string describing the CURLcode | ||||
| error code passed in the argument \fIerrornum\fP. | ||||
|   | ||||
| @@ -40,19 +40,28 @@ but be sure to FD_ZERO them before calling this function as | ||||
| otherwise remove any others. The \fIcurl_multi_perform(3)\fP function should be | ||||
| called as soon as one of them is ready to be read from or written to. | ||||
|  | ||||
| To be sure to have up-to-date results, you should call | ||||
| \fIcurl_multi_perform\fP until it does not return CURLM_CALL_MULTI_PERFORM | ||||
| prior to calling \fIcurl_multi_fdset\fP.  This will make sure that libcurl has | ||||
| updated the handles' socket states. | ||||
|  | ||||
| If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when | ||||
| this function returns. Otherwise it will contain the higher descriptor number | ||||
| libcurl set. | ||||
| libcurl set. When libcurl returns -1 in \fImax_fd\fP, it is because libcurl | ||||
| currently does something that isn't possible for your application to monitor | ||||
| with a socket and unfortunately you can then not know exactly when the current | ||||
| action is completed using select(). When max_fd returns with -1, you need to | ||||
| wait a while and then proceed and call \fIcurl_multi_perform\fP anyway. How | ||||
| long to wait? I would suggest 100 milliseconds at least, but you may want to | ||||
| test it out in your own particular conditions to find a suitable value. | ||||
|  | ||||
| When doing select(), you should use \fBcurl_multi_timeout\fP to figure out how | ||||
| long to wait for action. Call \fIcurl_multi_perform\fP even if no activity has | ||||
| been seen on the fd_sets after the timeout expires as otherwise internal | ||||
| retries and timeouts may not work as you'd think and want. | ||||
|  | ||||
| If one of the sockets used by libcurl happens to be larger than what can be | ||||
| set in an fd_set, which on POSIX systems means that the file descriptor is | ||||
| larger than FD_SETSIZE, then libcurl will try to not set it. Setting a too | ||||
| large file descriptor in an fd_set implies an out of bounds write which can | ||||
| cause crashes, or worse. The effect of NOT storing it will possibly save you | ||||
| from the crash, but will make your program NOT wait for sockets it should wait | ||||
| for... | ||||
| .SH RETURN VALUE | ||||
| CURLMcode type, general libcurl multi interface error code. See | ||||
| \fIlibcurl-errors(3)\fP | ||||
|   | ||||
| @@ -64,6 +64,11 @@ Cached DNS hosts will be shared across the easy handles using this shared | ||||
| object. Note that when you use the multi interface, all easy handles added to | ||||
| the same multi handle will share DNS cache by default without this having to | ||||
| be used! | ||||
| .IP CURL_LOCK_DATA_SSL_SESSION | ||||
| SSL session IDs will be shared accross the easy handles using this shared | ||||
| object. This will reduce the time spent in the SSL handshake when reconnecting | ||||
| to the same server. Note SSL session IDs are reused within the same easy handle | ||||
| by default. | ||||
| .RE | ||||
| .IP CURLSHOPT_UNSHARE | ||||
| This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that | ||||
|   | ||||
| @@ -66,9 +66,15 @@ remote server is probably not an OK FTP server. | ||||
| .IP "CURLE_REMOTE_ACCESS_DENIED (9)" | ||||
| We were denied access to the resource given in the URL.  For FTP, this occurs | ||||
| while trying to change to the remote directory. | ||||
| .IP "CURLE_FTP_ACCEPT_FAILED (10)" | ||||
| While waiting for the server to connect back when an active FTP session is | ||||
| used, an error code was sent over the control connection or similar. | ||||
| .IP "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. | ||||
| .IP "CURLE_FTP_ACCEPT_TIMEOUT (12)" | ||||
| During an active FTP session while waiting for the server to connect, the | ||||
| \fICURLOPT_ACCEPTTIMOUT_MS\fP (or the internal default) timeout expired. | ||||
| .IP "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. | ||||
| @@ -277,3 +283,6 @@ An invalid share object was passed to the function. | ||||
| .IP "CURLSHE_NOMEM (4)" | ||||
| Not enough memory was available. | ||||
| (Added in 7.12.0) | ||||
| .IP "CURLSHE_NOT_BUILT_IN (5)" | ||||
| The requsted sharing could not be done because the library you use don't have | ||||
| that particular feature enabled. (Added in 7.23.0) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| .\" *                            | (__| |_| |  _ <| |___ | ||||
| .\" *                             \___|\___/|_| \_\_____| | ||||
| .\" * | ||||
| .\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * | ||||
| .\" * This software is licensed as described in the file COPYING, which | ||||
| .\" * you should have received as part of this distribution. The terms | ||||
| @@ -82,14 +82,6 @@ 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. | ||||
|  | ||||
| A little note here about the return codes from the multi functions, and | ||||
| especially the \fIcurl_multi_perform(3)\fP: if you receive | ||||
| \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you should call | ||||
| \fIcurl_multi_perform(3)\fP again, before you select() on more actions. You | ||||
| don't have to do it immediately, but the return code means that libcurl may | ||||
| have more data available to return or that there may be more data to send off | ||||
| before it is "satisfied". | ||||
|  | ||||
| \fIcurl_multi_perform(3)\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 | ||||
| @@ -118,23 +110,40 @@ If you want to re-use an easy handle that was added to the multi handle for | ||||
| transfer, you must first remove it from the multi stack and then re-add it | ||||
| again (possibly after having altered some options at your own choice). | ||||
| .SH "MULTI_SOCKET" | ||||
| Since 7.16.0, the \fIcurl_multi_socket_action(3)\fP function offers a way for | ||||
| applications to not only avoid being forced to use select(), but it also | ||||
| offers a much more high-performance API that will make a significant | ||||
| difference for applications using large numbers of simultaneous connections. | ||||
| \fIcurl_multi_socket_action(3)\fP function offers a way for applications to | ||||
| not only avoid being forced to use select(), but it also offers a much more | ||||
| high-performance API that will make a significant difference for applications | ||||
| using large numbers of simultaneous connections. | ||||
|  | ||||
| \fIcurl_multi_socket_action(3)\fP is then used | ||||
| instead of \fIcurl_multi_perform(3)\fP. | ||||
| \fIcurl_multi_socket_action(3)\fP is then used instead of | ||||
| \fIcurl_multi_perform(3)\fP. | ||||
|  | ||||
| When using this API, you add easy handles to the multi handle just as with the | ||||
| normal multi interface. Then you also set two callbacks with the | ||||
| CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to | ||||
| \fIcurl_multi_setopt(3)\fP. | ||||
|  | ||||
| The API is then designed to inform your application about which sockets | ||||
| libcurl is currently using and for what activities (read and/or write) on | ||||
| those sockets your application is expected to wait for. | ||||
|  | ||||
| Your application must then make sure to receive all sockets informed about in | ||||
| the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given | ||||
| activity on them. When a socket has the given activity, you call | ||||
| \fIcurl_multi_socket_action(3)\fP specifying which socket and action there | ||||
| are. | ||||
|  | ||||
| The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that | ||||
| timeout expires, your application should call the | ||||
| \fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout. | ||||
| .SH "BLOCKING" | ||||
| A few areas in the code are still using blocking code, even when used from the | ||||
| multi interface. While we certainly want and intend for these to get fixed in | ||||
| the future, you should be aware of the following current restrictions: | ||||
|  | ||||
| .nf | ||||
|  - Name resolves on non-windows unless c-ares is used | ||||
|  - GnuTLS SSL connections | ||||
|  - Name resolves unless the c-ares or threaded-resolver backends are used | ||||
|  - NSS SSL connections | ||||
|  - Active FTP connections | ||||
|  - HTTP proxy CONNECT operations | ||||
|  - SOCKS proxy handshakes | ||||
|  - file:// transfers | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| .\" *                            | (__| |_| |  _ <| |___ | ||||
| .\" *                             \___|\___/|_| \_\_____| | ||||
| .\" * | ||||
| .\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| .\" * | ||||
| .\" * This software is licensed as described in the file COPYING, which | ||||
| .\" * you should have received as part of this distribution. The terms | ||||
| @@ -249,9 +249,11 @@ complication for you. Given simply the URL to a file, libcurl will take care | ||||
| of all the details needed to get the file moved from one machine to another. | ||||
|  | ||||
| .SH "Multi-threading Issues" | ||||
| The first basic rule is that you must \fBnever\fP share a libcurl handle (be | ||||
| it easy or multi or whatever) between multiple threads. Only use one handle in | ||||
| one thread at a time. | ||||
| The first basic rule is that you must \fBnever\fP simultaneously share a | ||||
| libcurl handle (be it easy or multi or whatever) between multiple | ||||
| threads. Only use one handle in one thread at any time. You can pass the | ||||
| handles around among threads, but you must never use a single handle from more | ||||
| than one thread at any given time. | ||||
|  | ||||
| libcurl is completely thread safe, except for two issues: signals and SSL/TLS | ||||
| handlers. Signals are used for timing out name resolves (during DNS lookup) - | ||||
| @@ -815,10 +817,6 @@ This header is required by HTTP 1.1 and even many 1.0 servers and should be | ||||
| the name of the server we want to talk to. This includes the port number if | ||||
| anything but default. | ||||
|  | ||||
| .IP "Pragma" | ||||
| \&"no-cache". Tells a possible proxy to not grab a copy from the cache but to | ||||
| fetch a fresh one. | ||||
|  | ||||
| .IP "Accept" | ||||
| \&"*/*". | ||||
|  | ||||
| @@ -1301,9 +1299,7 @@ ones at any time), you start the transfers by calling | ||||
|  | ||||
| \fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as | ||||
| possible and then return back control to your program. It is designed to never | ||||
| block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again soon, | ||||
| as that is a signal that it still has local data to send or remote data to | ||||
| receive. | ||||
| block. | ||||
|  | ||||
| The best usage of this interface is when you do a select() on all possible | ||||
| file descriptors or sockets to know when to call libcurl again. This also | ||||
| @@ -1339,9 +1335,21 @@ to figure out success on each individual transfer. | ||||
|  [ seeding, passwords, keys, certificates, ENGINE, ca certs ] | ||||
|  | ||||
| .SH "Sharing Data Between Easy Handles" | ||||
| You can share some data between easy handles when the easy interface is used, | ||||
| and some data is share automatically when you use the multi interface. | ||||
|  | ||||
|  [ fill in ] | ||||
| When you add easy handles to a multi handle, these easy handles will | ||||
| automatically share a lot of the data that otherwise would be kept on a | ||||
| per-easy handle basis when the easy interface is used. | ||||
|  | ||||
| The DNS cache is shared between handles within a multi handle, making | ||||
| subsequent name resolvings faster and the connection pool that is kept to | ||||
| better allow persistent connections and connection re-use is shared. If you're | ||||
| using the easy interface, you can still share these between specific easy | ||||
| handles by using the share interface, see \fIlibcurl-share(3)\fP. | ||||
|  | ||||
| Some things are never shared automatically, not within multi handles, like for | ||||
| example cookies so the only way to share that is with the share interface. | ||||
| .SH "Footnotes" | ||||
|  | ||||
| .IP "[1]" | ||||
|   | ||||
| @@ -146,7 +146,7 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG], | ||||
|            _libcurl_save_libs=$LIBS | ||||
|            LIBS="$LIBCURL $LIBS" | ||||
|  | ||||
|            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <curl/curl.h>],[ | ||||
|            AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[ | ||||
| /* Try and use a few common options to force a failure if we are | ||||
|    missing symbols or can't link. */ | ||||
| int x; | ||||
| @@ -157,7 +157,8 @@ x=CURLOPT_FILE; | ||||
| x=CURLOPT_ERRORBUFFER; | ||||
| x=CURLOPT_STDERR; | ||||
| x=CURLOPT_VERBOSE; | ||||
| ])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) | ||||
| if (x) ; | ||||
| ]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) | ||||
|  | ||||
|            CPPFLAGS=$_libcurl_save_cppflags | ||||
|            LIBS=$_libcurl_save_libs | ||||
|   | ||||
| @@ -45,6 +45,8 @@ CURLE_COULDNT_RESOLVE_PROXY     7.1 | ||||
| CURLE_FAILED_INIT               7.1 | ||||
| CURLE_FILESIZE_EXCEEDED         7.10.8 | ||||
| CURLE_FILE_COULDNT_READ_FILE    7.1 | ||||
| CURLE_FTP_ACCEPT_FAILED         7.24.0 | ||||
| CURLE_FTP_ACCEPT_TIMEOUT        7.24.0 | ||||
| CURLE_FTP_ACCESS_DENIED         7.1 | ||||
| CURLE_FTP_BAD_DOWNLOAD_RESUME   7.1           7.1 | ||||
| CURLE_FTP_BAD_FILE_LIST         7.21.0 | ||||
| @@ -286,6 +288,7 @@ CURLOPTTYPE_FUNCTIONPOINT       7.1 | ||||
| CURLOPTTYPE_LONG                7.1 | ||||
| CURLOPTTYPE_OBJECTPOINT         7.1 | ||||
| CURLOPTTYPE_OFF_T               7.11.0 | ||||
| CURLOPT_ACCEPTTIMEOUT_MS        7.24.0 | ||||
| CURLOPT_ACCEPT_ENCODING         7.21.6 | ||||
| CURLOPT_ADDRESS_SCOPE           7.19.0 | ||||
| CURLOPT_APPEND                  7.17.0 | ||||
| @@ -320,6 +323,7 @@ CURLOPT_DEBUGDATA               7.9.6 | ||||
| CURLOPT_DEBUGFUNCTION           7.9.6 | ||||
| CURLOPT_DIRLISTONLY             7.17.0 | ||||
| CURLOPT_DNS_CACHE_TIMEOUT       7.9.3 | ||||
| CURLOPT_DNS_SERVERS             7.24.0 | ||||
| CURLOPT_DNS_USE_GLOBAL_CACHE    7.9.3         7.11.1 | ||||
| CURLOPT_EGDSOCKET               7.7 | ||||
| CURLOPT_ENCODING                7.10 | ||||
| @@ -550,6 +554,7 @@ CURLSHE_BAD_OPTION              7.10.3 | ||||
| CURLSHE_INVALID                 7.10.3 | ||||
| CURLSHE_IN_USE                  7.10.3 | ||||
| CURLSHE_NOMEM                   7.12.0 | ||||
| CURLSHE_NOT_BUILT_IN            7.23.0 | ||||
| CURLSHE_OK                      7.10.3 | ||||
| CURLSHOPT_LOCKFUNC              7.10.3 | ||||
| CURLSHOPT_NONE                  7.10.3 | ||||
|   | ||||
							
								
								
									
										100
									
								
								docs/libcurl/symbols.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										100
									
								
								docs/libcurl/symbols.pl
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| #!/usr/bin/perl | ||||
| #*************************************************************************** | ||||
| #                                  _   _ ____  _ | ||||
| #  Project                     ___| | | |  _ \| | | ||||
| #                             / __| | | | |_) | | | ||||
| #                            | (__| |_| |  _ <| |___ | ||||
| #                             \___|\___/|_| \_\_____| | ||||
| # | ||||
| # Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| # | ||||
| # This software is licensed as described in the file COPYING, which | ||||
| # you should have received as part of this distribution. The terms | ||||
| # are also available at http://curl.haxx.se/docs/copyright.html. | ||||
| # | ||||
| # You may opt to use, copy, modify, merge, publish, distribute and/or sell | ||||
| # copies of the Software, and permit persons to whom the Software is | ||||
| # furnished to do so, under the terms of the COPYING file. | ||||
| # | ||||
| # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||||
| # KIND, either express or implied. | ||||
| # | ||||
| ########################################################################### | ||||
| # | ||||
| # Experience has shown that the symbols-in-versions file is very useful to | ||||
| # applications that want to build with a wide range of libcurl versions. | ||||
| # It is however easy to get it wrong and the source gets a bit messy with all | ||||
| # the fixed numerical comparisions. | ||||
| # | ||||
| # The point of this script is to provide an easy-to-use macro for libcurl- | ||||
| # using applications to do preprocessor checks for specific libcurl defines, | ||||
| # and yet make the code clearly show what the macro is used for. | ||||
| # | ||||
| # Run this script and generate libcurl-symbols.h and then use that header in | ||||
| # a fashion similar to: | ||||
| # | ||||
| # #include "libcurl-symbols.h" | ||||
| # | ||||
| # #if LIBCURL_HAS(CURLOPT_MUTE) | ||||
| #   has mute | ||||
| # #else | ||||
| #   no mute | ||||
| # #endif | ||||
| # | ||||
| # | ||||
| open F, "<symbols-in-versions"; | ||||
|  | ||||
| sub str2num { | ||||
|     my ($str)=@_; | ||||
|     if($str =~ /([0-9]*)\.([0-9]*)\.*([0-9]*)/) { | ||||
|         return sprintf("0x%06x", $1<<16 | $2 << 8 | $3); | ||||
|     } | ||||
| } | ||||
|  | ||||
| print <<EOS | ||||
|  | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| #define LIBCURL_HAS(x) \\ | ||||
|   (defined(x ## _FIRST) && (x ## _FIRST <= LIBCURL_VERSION_NUM) && \\ | ||||
|    (!defined(x ## _LAST) || ( x ## _LAST >= LIBCURL_VERSION_NUM))) | ||||
|  | ||||
| EOS | ||||
|     ; | ||||
|  | ||||
| while(<F>) { | ||||
|     if(/^(CURL[^ ]*)[ \t]*(.*)/) { | ||||
|         my ($sym, $vers)=($1, $2); | ||||
|  | ||||
|         my $intr; | ||||
|         my $rm; | ||||
|         my $dep; | ||||
|  | ||||
|         # is there removed info? | ||||
|         if($vers =~ /([\d.]+)[ \t-]+([\d.]+)[ \t]+([\d.]+)/) { | ||||
|             ($intr, $dep, $rm)=($1, $2, $3); | ||||
|         } | ||||
|         # is it a dep-only line? | ||||
|         elsif($vers =~ /([\d.]+)[ \t-]+([\d.]+)/) { | ||||
|             ($intr, $dep)=($1, $2); | ||||
|         } | ||||
|         else { | ||||
|             $intr = $vers; | ||||
|         } | ||||
|  | ||||
|         my $inum = str2num($intr); | ||||
|  | ||||
|         print <<EOS | ||||
| #define ${sym}_FIRST $inum /* Added in $intr */ | ||||
| EOS | ||||
| ; | ||||
|         my $irm = str2num($rm); | ||||
|         if($rm) { | ||||
|         print <<EOS | ||||
| #define ${sym}_LAST $irm /* Last featured in $rm */ | ||||
| EOS | ||||
| ; | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -7,7 +7,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -69,7 +69,7 @@ | ||||
|    require it! */ | ||||
| #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ | ||||
|     defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ | ||||
|     defined(ANDROID) || \ | ||||
|     defined(ANDROID) || defined(__ANDROID__) || \ | ||||
|    (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) | ||||
| #include <sys/select.h> | ||||
| #endif | ||||
| @@ -187,10 +187,10 @@ typedef int (*curl_progress_callback)(void *clientp, | ||||
| #define CURL_MAX_HTTP_HEADER (100*1024) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* This is a magic return code for the write callback that, when returned, | ||||
|    will signal libcurl to pause receiving on the current transfer. */ | ||||
| #define CURL_WRITEFUNC_PAUSE 0x10000001 | ||||
|  | ||||
| typedef size_t (*curl_write_callback)(char *buffer, | ||||
|                                       size_t size, | ||||
|                                       size_t nitems, | ||||
| @@ -411,9 +411,12 @@ typedef enum { | ||||
|   CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server | ||||
|                                     due to lack of access - when login fails | ||||
|                                     this is not returned. */ | ||||
|   CURLE_OBSOLETE10,              /* 10 - NOT USED */ | ||||
|   CURLE_FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for | ||||
|                                     7.15.4, reused in Dec 2011 for 7.24.0]*/ | ||||
|   CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */ | ||||
|   CURLE_OBSOLETE12,              /* 12 - NOT USED */ | ||||
|   CURLE_FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server | ||||
|                                     [was obsoleted in August 2007 for 7.17.0, | ||||
|                                     reused in Dec 2011 for 7.24.0]*/ | ||||
|   CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */ | ||||
|   CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */ | ||||
|   CURLE_FTP_CANT_GET_HOST,       /* 15 */ | ||||
| @@ -511,13 +514,16 @@ typedef enum { | ||||
|   CURLE_RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */ | ||||
|   CURLE_FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */ | ||||
|   CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */ | ||||
|  | ||||
|   CURL_LAST /* never use! */ | ||||
| } CURLcode; | ||||
|  | ||||
| #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all | ||||
|                           the obsolete stuff removed! */ | ||||
|  | ||||
| /* Previously obsoletes error codes re-used in 7.24.0 */ | ||||
| #define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED | ||||
| #define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT | ||||
|  | ||||
| /*  compatibility with older names */ | ||||
| #define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING | ||||
|  | ||||
| @@ -1486,6 +1492,13 @@ typedef enum { | ||||
|   /* allow GSSAPI credential delegation */ | ||||
|   CINIT(GSSAPI_DELEGATION, LONG, 210), | ||||
|  | ||||
|   /* Set the name servers to use for DNS resolution */ | ||||
|   CINIT(DNS_SERVERS, OBJECTPOINT, 211), | ||||
|  | ||||
|   /* Time-out accept operations (currently for FTP only) after this amount | ||||
|      of miliseconds. */ | ||||
|   CINIT(ACCEPTTIMEOUT_MS, LONG, 212), | ||||
|  | ||||
|   CURLOPT_LASTENTRY /* the last unused */ | ||||
| } CURLoption; | ||||
|  | ||||
| @@ -2014,7 +2027,8 @@ typedef enum { | ||||
|   CURLSHE_BAD_OPTION, /* 1 */ | ||||
|   CURLSHE_IN_USE,     /* 2 */ | ||||
|   CURLSHE_INVALID,    /* 3 */ | ||||
|   CURLSHE_NOMEM,      /* out of memory */ | ||||
|   CURLSHE_NOMEM,      /* 4 out of memory */ | ||||
|   CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ | ||||
|   CURLSHE_LAST        /* never use */ | ||||
| } CURLSHcode; | ||||
|  | ||||
|   | ||||
| @@ -30,12 +30,12 @@ | ||||
|  | ||||
| /* This is the version number of the libcurl package from which this header | ||||
|    file origins: */ | ||||
| #define LIBCURL_VERSION "7.22.0-DEV" | ||||
| #define LIBCURL_VERSION "7.24.0-DEV" | ||||
|  | ||||
| /* The numeric version number is also available "in parts" by using these | ||||
|    defines: */ | ||||
| #define LIBCURL_VERSION_MAJOR 7 | ||||
| #define LIBCURL_VERSION_MINOR 22 | ||||
| #define LIBCURL_VERSION_MINOR 24 | ||||
| #define LIBCURL_VERSION_PATCH 0 | ||||
|  | ||||
| /* This is the numeric version of the libcurl version number, meant for easier | ||||
| @@ -53,7 +53,7 @@ | ||||
|    and it is always a greater number in a more recent release. It makes | ||||
|    comparisons with greater than and less than work. | ||||
| */ | ||||
| #define LIBCURL_VERSION_NUM 0x071600 | ||||
| #define LIBCURL_VERSION_NUM 0x071800 | ||||
|  | ||||
| /* | ||||
|  * This is the date and time when the full source package was created. The | ||||
|   | ||||
| @@ -392,7 +392,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist, | ||||
| /* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ | ||||
| /* XXX: also check size of an char[] array? */ | ||||
| #define _curl_is_error_buffer(expr)                                           \ | ||||
|   (__builtin_types_compatible_p(__typeof__(expr), char *) ||                  \ | ||||
|   (_curl_is_NULL(expr) ||                                                     \ | ||||
|    __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \ | ||||
|    __builtin_types_compatible_p(__typeof__(expr), char[])) | ||||
|  | ||||
| /* evaluates to true if expr is of type (const) void* or (const) FILE* */ | ||||
| @@ -521,7 +522,11 @@ typedef int (_curl_progress_callback2)(const void *, | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback1) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback2) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback3) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback4)) | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback4) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback5) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback6) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback7) ||                \ | ||||
|    _curl_callback_compatible((expr), _curl_debug_callback8)) | ||||
| typedef int (_curl_debug_callback1) (CURL *, | ||||
|     curl_infotype, char *, size_t, void *); | ||||
| typedef int (_curl_debug_callback2) (CURL *, | ||||
| @@ -530,6 +535,14 @@ typedef int (_curl_debug_callback3) (CURL *, | ||||
|     curl_infotype, const char *, size_t, void *); | ||||
| typedef int (_curl_debug_callback4) (CURL *, | ||||
|     curl_infotype, const char *, size_t, const void *); | ||||
| typedef int (_curl_debug_callback5) (CURL *, | ||||
|     curl_infotype, unsigned char *, size_t, void *); | ||||
| typedef int (_curl_debug_callback6) (CURL *, | ||||
|     curl_infotype, unsigned char *, size_t, const void *); | ||||
| typedef int (_curl_debug_callback7) (CURL *, | ||||
|     curl_infotype, const unsigned char *, size_t, void *); | ||||
| typedef int (_curl_debug_callback8) (CURL *, | ||||
|     curl_infotype, const unsigned char *, size_t, const void *); | ||||
|  | ||||
| /* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ | ||||
| /* this is getting even messier... */ | ||||
|   | ||||
							
								
								
									
										1
									
								
								lib/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								lib/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -10,3 +10,4 @@ libcurl.plist.dist | ||||
| libcurl.vcproj | ||||
| vc6libcurl.dsp | ||||
| Makefile.vc10.dist | ||||
| libcurl.vers | ||||
|   | ||||
| @@ -116,7 +116,11 @@ if MIMPURE | ||||
| MIMPURE = -mimpure-text | ||||
| endif | ||||
|  | ||||
| libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(LIBCURL_LIBS) | ||||
| if VERSIONED_SYMBOLS | ||||
| VERSIONED_SYMBOLS = -Wl,--version-script=libcurl.vers | ||||
| endif | ||||
|  | ||||
| libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(VERSIONED_SYMBOLS) $(LIBCURL_LIBS) | ||||
|  | ||||
| # unit testing static library built only along with unit tests | ||||
| if BUILD_UNITTESTS | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| ######################################################################### | ||||
| ########################################################################### | ||||
| # | ||||
| ## Makefile for building libcurl.a with MingW32 (GCC-3.2 or later) | ||||
| ## and optionally OpenSSL (0.9.8), libssh2 (1.2), zlib (1.2.5), librtmp (2.3) | ||||
| ## Makefile for building libcurl.a with MingW (GCC-3.2 or later) | ||||
| ## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3) | ||||
| ## | ||||
| ## Usage:   mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...] | ||||
| ## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn | ||||
| @@ -9,10 +9,8 @@ | ||||
| ## Hint: you can also set environment vars to control the build, f.e.: | ||||
| ## set ZLIB_PATH=c:/zlib-1.2.5 | ||||
| ## set ZLIB=1 | ||||
| ## | ||||
| ## Comments to: Troy Engel <tengel@sonic.net> or | ||||
| ##              Joern Hartroth <hartroth@acm.org> | ||||
| ######################################################################### | ||||
| # | ||||
| ########################################################################### | ||||
|  | ||||
| # Edit the path below to point to the base of your Zlib sources. | ||||
| ifndef ZLIB_PATH | ||||
| @@ -22,6 +20,15 @@ endif | ||||
| ifndef OPENSSL_PATH | ||||
| OPENSSL_PATH = ../../openssl-0.9.8r | ||||
| endif | ||||
| ifndef OPENSSL_INCLUDE | ||||
| OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc | ||||
| endif | ||||
| ifndef OPENSSL_LIBPATH | ||||
| OPENSSL_LIBPATH = $(OPENSSL_PATH)/out | ||||
| endif | ||||
| ifndef OPENSSL_LIBS | ||||
| OPENSSL_LIBS = -leay32 -lssl32 | ||||
| endif | ||||
| # Edit the path below to point to the base of your LibSSH2 package. | ||||
| ifndef LIBSSH2_PATH | ||||
| LIBSSH2_PATH = ../../libssh2-1.3.0 | ||||
| @@ -34,7 +41,7 @@ endif | ||||
| ifndef LIBIDN_PATH | ||||
| LIBIDN_PATH = ../../libidn-1.18 | ||||
| endif | ||||
| # Edit the path below to point to the base of your MS idndlpackage.  | ||||
| # Edit the path below to point to the base of your MS IDN package. | ||||
| # Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 | ||||
| # http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815 | ||||
| ifndef WINIDN_PATH | ||||
| @@ -45,9 +52,11 @@ ifndef LDAP_SDK | ||||
| LDAP_SDK = c:/novell/ndk/cldapsdk/win32 | ||||
| endif | ||||
|  | ||||
| PROOT = .. | ||||
|  | ||||
| # Edit the path below to point to the base of your c-ares package. | ||||
| ifndef LIBCARES_PATH | ||||
| LIBCARES_PATH = ../ares | ||||
| LIBCARES_PATH = $(PROOT)/ares | ||||
| endif | ||||
|  | ||||
| # Edit the var below to set to your architecture or set environment var. | ||||
| @@ -57,6 +66,7 @@ endif | ||||
|  | ||||
| CC = gcc | ||||
| CFLAGS = -g -O2 -Wall | ||||
| CFLAGS += -fno-strict-aliasing | ||||
| ifeq ($(ARCH),w64) | ||||
| CFLAGS += -D_AMD64_ | ||||
| endif | ||||
| @@ -65,10 +75,12 @@ LDFLAGS = -s | ||||
| AR = ar | ||||
| RANLIB = ranlib | ||||
| RC = windres | ||||
| RCFLAGS = --include-dir=../include -DDEBUGBUILD=0 -O COFF -i | ||||
| RM = del /q /f 2>NUL | ||||
| RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O COFF -i | ||||
| STRIP = strip -g | ||||
|  | ||||
| RM = del /q /f 2>NUL | ||||
| CP = copy | ||||
|  | ||||
| ######################################################## | ||||
| ## Nothing more to do below this line! | ||||
|  | ||||
| @@ -115,10 +127,11 @@ endif | ||||
|  | ||||
| INCLUDES = -I. -I../include | ||||
| CFLAGS += -DBUILDING_LIBCURL | ||||
|  | ||||
| ifdef ARES | ||||
|   INCLUDES += -I$(LIBCARES_PATH) | ||||
|   INCLUDES += -I"$(LIBCARES_PATH)" | ||||
|   CFLAGS += -DUSE_ARES | ||||
|   DLL_LIBS += -L$(LIBCARES_PATH) -lcares | ||||
|   DLL_LIBS += -L"$(LIBCARES_PATH)" -lcares | ||||
|   libcurl_dll_DEPENDENCIES = $(LIBCARES_PATH)/libcares.a | ||||
| endif | ||||
| ifdef RTMP | ||||
| @@ -129,24 +142,24 @@ endif | ||||
| ifdef SSH2 | ||||
|   INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32" | ||||
|   CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H | ||||
|   DLL_LIBS += -L$(LIBSSH2_PATH)/win32 -lssh2 | ||||
|   DLL_LIBS += -L"$(LIBSSH2_PATH)/win32" -lssh2 | ||||
| endif | ||||
| ifdef SSL | ||||
|   INCLUDES += -I"$(OPENSSL_PATH)/outinc" -I"$(OPENSSL_PATH)/outinc/openssl" | ||||
|   INCLUDES += -I"$(OPENSSL_INCLUDE)" | ||||
|   CFLAGS += -DUSE_SSLEAY -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \ | ||||
|             -DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 \ | ||||
|             -DCURL_WANTS_CA_BUNDLE_ENV | ||||
|   DLL_LIBS += -L$(OPENSSL_PATH)/out -leay32 -lssl32 | ||||
|   DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) | ||||
| endif | ||||
| ifdef ZLIB | ||||
|   INCLUDES += -I"$(ZLIB_PATH)" | ||||
|   CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H | ||||
|   DLL_LIBS += -L$(ZLIB_PATH) -lz | ||||
|   DLL_LIBS += -L"$(ZLIB_PATH)" -lz | ||||
| endif | ||||
| ifdef IDN | ||||
|   INCLUDES += -I"$(LIBIDN_PATH)/include" | ||||
|   CFLAGS += -DUSE_LIBIDN | ||||
|   DLL_LIBS += -L$(LIBIDN_PATH)/lib -lidn | ||||
|   DLL_LIBS += -L"$(LIBIDN_PATH)/lib" -lidn | ||||
| else | ||||
| ifdef WINIDN | ||||
|   CFLAGS += -DUSE_WIN32_IDN | ||||
| @@ -161,7 +174,7 @@ ifdef SPNEGO | ||||
|   CFLAGS += -DHAVE_SPNEGO | ||||
| endif | ||||
| ifdef IPV6 | ||||
|   CFLAGS += -DENABLE_IPV6 | ||||
|   CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501 | ||||
| endif | ||||
| ifdef LDAPS | ||||
|   CFLAGS += -DHAVE_LDAP_SSL | ||||
| @@ -182,7 +195,6 @@ DLL_LIBS += -lwldap32 | ||||
| endif | ||||
| endif | ||||
| DLL_LIBS += -lws2_32 | ||||
| COMPILE = $(CC) $(INCLUDES) $(CFLAGS) | ||||
|  | ||||
| # Makefile.inc provides the CSOURCES and HHEADERS defines | ||||
| include Makefile.inc | ||||
| @@ -196,7 +208,6 @@ libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS)) | ||||
|  | ||||
| RESOURCE = libcurl.res | ||||
|  | ||||
| .SUFFIXES: .rc .res | ||||
|  | ||||
| all: $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) | ||||
|  | ||||
| @@ -213,20 +224,25 @@ $(libcurl_dll_LIBRARY): $(libcurl_a_OBJECTS) $(RESOURCE) $(libcurl_dll_DEPENDENC | ||||
| 	$(CC) $(LDFLAGS) -shared -Wl,--out-implib,$(libcurl_dll_a_LIBRARY) \ | ||||
| 	  -o $@ $(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS) | ||||
|  | ||||
| .c.o: | ||||
| 	$(COMPILE) -c $< | ||||
| %.o: %.c $(PROOT)/include/curl/curlbuild.h | ||||
| 	$(CC) $(INCLUDES) $(CFLAGS) -c $< | ||||
|  | ||||
| .rc.res: | ||||
| %.res: %.rc | ||||
| 	$(RC) $(RCFLAGS) $< -o $@ | ||||
|  | ||||
| clean: | ||||
| ifeq "$(wildcard $(PROOT)/include/curl/curlbuild.h.dist)" "$(PROOT)/include/curl/curlbuild.h.dist" | ||||
| 	-$(RM) $(subst /,\,$(PROOT)/include/curl/curlbuild.h) | ||||
| endif | ||||
| 	-$(RM) $(libcurl_a_OBJECTS) $(RESOURCE) | ||||
|  | ||||
| distclean vclean: clean | ||||
| 	-$(RM) $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_a_LIBRARY) | ||||
|  | ||||
| FORCE: ; | ||||
|  | ||||
| $(LIBCARES_PATH)/libcares.a: | ||||
| 	$(MAKE) -C $(LIBCARES_PATH) -f Makefile.m32 | ||||
|  | ||||
| $(PROOT)/include/curl/curlbuild.h: | ||||
| 	@echo Creating $@ | ||||
| 	@$(CP) $(subst /,\,$@).dist $(subst /,\,$@) | ||||
|  | ||||
|   | ||||
| @@ -42,6 +42,11 @@ ifndef LIBRTMP_PATH | ||||
| LIBRTMP_PATH = ../../librtmp-2.3 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your fbopenssl package. | ||||
| ifndef FBOPENSSL_PATH | ||||
| FBOPENSSL_PATH = ../../fbopenssl-0.4 | ||||
| endif | ||||
|  | ||||
| # Edit the path below to point to the base of your c-ares package. | ||||
| ifndef LIBCARES_PATH | ||||
| LIBCARES_PATH = ../ares | ||||
| @@ -181,6 +186,43 @@ CURL_LIB = ../lib | ||||
|  | ||||
| INCLUDES = -I$(CURL_INC) -I$(CURL_LIB) | ||||
|  | ||||
| ifeq ($(findstring -static,$(CFG)),-static) | ||||
| LINK_STATIC = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ares,$(CFG)),-ares) | ||||
| WITH_ARES = 1 | ||||
| endif | ||||
| ifeq ($(findstring -rtmp,$(CFG)),-rtmp) | ||||
| WITH_RTMP = 1 | ||||
| WITH_SSL = 1 | ||||
| WITH_ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ssh2,$(CFG)),-ssh2) | ||||
| WITH_SSH2 = 1 | ||||
| WITH_SSL = 1 | ||||
| WITH_ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -axtls,$(CFG)),-axtls) | ||||
| WITH_AXTLS = 1 | ||||
| WITH_SSL = | ||||
| else | ||||
| ifeq ($(findstring -ssl,$(CFG)),-ssl) | ||||
| WITH_SSL = 1 | ||||
| endif | ||||
| endif | ||||
| ifeq ($(findstring -zlib,$(CFG)),-zlib) | ||||
| WITH_ZLIB = 1 | ||||
| endif | ||||
| ifeq ($(findstring -idn,$(CFG)),-idn) | ||||
| WITH_IDN = 1 | ||||
| endif | ||||
| ifeq ($(findstring -spnego,$(CFG)),-spnego) | ||||
| WITH_SPNEGO = 1 | ||||
| endif | ||||
| ifeq ($(findstring -ipv6,$(CFG)),-ipv6) | ||||
| ENABLE_IPV6 = 1 | ||||
| endif | ||||
|  | ||||
| ifdef WITH_ARES | ||||
| 	INCLUDES += -I$(LIBCARES_PATH) | ||||
| 	LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT) | ||||
| @@ -204,6 +246,10 @@ ifdef WITH_SSL | ||||
| 	LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) | ||||
| 	IMPORTS += GetProcessSwitchCount RunningProcess | ||||
| 	INSTDEP += ca-bundle.crt | ||||
| ifdef WITH_SPNEGO | ||||
| 	INCLUDES += -I$(FBOPENSSL_PATH)/include | ||||
| 	LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT) | ||||
| endif | ||||
| else | ||||
| ifdef WITH_AXTLS | ||||
| 	INCLUDES += -I$(AXTLS_PATH)/inc | ||||
| @@ -584,6 +630,9 @@ ifdef WITH_SSL | ||||
| 	@echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@ | ||||
| ifdef WITH_SPNEGO | ||||
| 	@echo $(DL)#define HAVE_SPNEGO 1$(DL) >> $@ | ||||
| endif | ||||
| else | ||||
| ifdef WITH_AXTLS | ||||
| 	@echo $(DL)#define USE_AXTLS 1$(DL) >> $@ | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -26,9 +26,11 @@ | ||||
|  * Telnet option defines. Add more here if in need. | ||||
|  */ | ||||
| #define CURL_TELOPT_BINARY   0  /* binary 8bit data */ | ||||
| #define CURL_TELOPT_ECHO     1  /* just echo! */ | ||||
| #define CURL_TELOPT_SGA      3  /* Suppress Go Ahead */ | ||||
| #define CURL_TELOPT_EXOPL  255  /* EXtended OPtions List */ | ||||
| #define CURL_TELOPT_TTYPE   24  /* Terminal TYPE */ | ||||
| #define CURL_TELOPT_NAWS    31  /* Negotiate About Window Size */ | ||||
| #define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ | ||||
|  | ||||
| #define CURL_TELOPT_NEW_ENVIRON 39  /* NEW ENVIRONment variables */ | ||||
|   | ||||
| @@ -227,18 +227,19 @@ int Curl_resolver_getsock(struct connectdata *conn, | ||||
|   struct timeval maxtime; | ||||
|   struct timeval timebuf; | ||||
|   struct timeval *timeout; | ||||
|   long milli; | ||||
|   int max = ares_getsock((ares_channel)conn->data->state.resolver, | ||||
|                          (ares_socket_t *)socks, numsocks); | ||||
|  | ||||
|  | ||||
|   maxtime.tv_sec = CURL_TIMEOUT_RESOLVE; | ||||
|   maxtime.tv_usec = 0; | ||||
|  | ||||
|   timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime, | ||||
|                          &timebuf); | ||||
|  | ||||
|   Curl_expire(conn->data, | ||||
|               (timeout->tv_sec * 1000) + (timeout->tv_usec/1000)); | ||||
|   milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000); | ||||
|   if(milli == 0) | ||||
|     milli += 10; | ||||
|   Curl_expire(conn->data, milli); | ||||
|  | ||||
|   return max; | ||||
| } | ||||
| @@ -330,9 +331,12 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn, | ||||
|     res->temp_ai = NULL; | ||||
|     destroy_async_data(&conn->async); | ||||
|     if(!conn->async.dns) { | ||||
|       failf(data, "Could not resolve host: %s (%s)", conn->host.dispname, | ||||
|       failf(data, "Could not resolve %s: %s (%s)", | ||||
|             conn->bits.proxy?"proxy":"host", | ||||
|             conn->host.dispname, | ||||
|             ares_strerror(conn->async.status)); | ||||
|       return CURLE_COULDNT_RESOLVE_HOST; | ||||
|       return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: | ||||
|         CURLE_COULDNT_RESOLVE_HOST; | ||||
|     } | ||||
|     *dns = conn->async.dns; | ||||
|   } | ||||
| @@ -418,7 +422,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, | ||||
|   if(!conn->async.dns) { | ||||
|     /* a name was not resolved */ | ||||
|     if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) { | ||||
|       if(conn->bits.httpproxy) { | ||||
|       if(conn->bits.proxy) { | ||||
|         failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname); | ||||
|         rc = CURLE_COULDNT_RESOLVE_PROXY; | ||||
|       } | ||||
| @@ -428,7 +432,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, | ||||
|       } | ||||
|     } | ||||
|     else if(conn->async.done) { | ||||
|       if(conn->bits.httpproxy) { | ||||
|       if(conn->bits.proxy) { | ||||
|         failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname, | ||||
|               ares_strerror(conn->async.status)); | ||||
|         rc = CURLE_COULDNT_RESOLVE_PROXY; | ||||
| @@ -600,4 +604,31 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, | ||||
|   } | ||||
|   return NULL; /* no struct yet */ | ||||
| } | ||||
|  | ||||
| CURLcode Curl_set_dns_servers(struct SessionHandle *data, | ||||
|                               char *servers) | ||||
| { | ||||
|   CURLcode result = CURLE_NOT_BUILT_IN; | ||||
| #if (ARES_VERSION >= 0x010704) | ||||
|   int ares_result = ares_set_servers_csv(data->state.resolver, servers); | ||||
|   switch(ares_result) { | ||||
|   case ARES_SUCCESS: | ||||
|     result = CURLE_OK; | ||||
|     break; | ||||
|   case ARES_ENOMEM: | ||||
|     result = CURLE_OUT_OF_MEMORY; | ||||
|     break; | ||||
|   case ARES_ENOTINITIALIZED: | ||||
|   case ARES_ENODATA: | ||||
|   case ARES_EBADSTR: | ||||
|   default: | ||||
|     result = CURLE_BAD_FUNCTION_ARGUMENT; | ||||
|     break; | ||||
|   } | ||||
| #else /* too old c-ares version! */ | ||||
|   (void)data; | ||||
|   (void)servers; | ||||
| #endif | ||||
|   return result; | ||||
| } | ||||
| #endif /* CURLRES_ARES */ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -175,7 +175,6 @@ struct thread_sync_data { | ||||
|  | ||||
| struct thread_data { | ||||
|   curl_thread_t thread_hnd; | ||||
|   curl_socket_t dummy_sock; | ||||
|   unsigned int poll_interval; | ||||
|   int interval_end; | ||||
|   struct thread_sync_data tsd; | ||||
| @@ -329,9 +328,6 @@ static void destroy_async_data (struct Curl_async *async) | ||||
|   if(async->os_specific) { | ||||
|     struct thread_data *td = (struct thread_data*) async->os_specific; | ||||
|  | ||||
|     if(td->dummy_sock != CURL_SOCKET_BAD) | ||||
|       sclose(td->dummy_sock); | ||||
|  | ||||
|     if(td->thread_hnd != curl_thread_t_null) | ||||
|       Curl_thread_join(&td->thread_hnd); | ||||
|  | ||||
| @@ -364,7 +360,6 @@ static bool init_resolve_thread (struct connectdata *conn, | ||||
|   conn->async.done = FALSE; | ||||
|   conn->async.status = 0; | ||||
|   conn->async.dns = NULL; | ||||
|   td->dummy_sock = CURL_SOCKET_BAD; | ||||
|   td->thread_hnd = curl_thread_t_null; | ||||
|  | ||||
|   if(!init_thread_sync_data(&td->tsd, hostname, port, hints)) | ||||
| @@ -375,16 +370,6 @@ static bool init_resolve_thread (struct connectdata *conn, | ||||
|   if(!conn->async.hostname) | ||||
|     goto err_exit; | ||||
|  | ||||
| #ifdef WIN32 | ||||
|   /* This socket is only to keep Curl_resolver_fdset() and select() happy; | ||||
|    * should never become signalled for read since it's unbound but | ||||
|    * Windows needs at least 1 socket in select(). | ||||
|    */ | ||||
|   td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); | ||||
|   if(td->dummy_sock == CURL_SOCKET_BAD) | ||||
|     goto err_exit; | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_GETADDRINFO | ||||
|   td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd); | ||||
| #else | ||||
| @@ -574,17 +559,9 @@ int Curl_resolver_getsock(struct connectdata *conn, | ||||
|                           curl_socket_t *socks, | ||||
|                           int numsocks) | ||||
| { | ||||
|   const struct thread_data *td = | ||||
|     (const struct thread_data *) conn->async.os_specific; | ||||
|  | ||||
|   if(td && td->dummy_sock != CURL_SOCKET_BAD) { | ||||
|     if(numsocks) { | ||||
|       /* return one socket waiting for readable, even though this is just | ||||
|          a dummy */ | ||||
|       socks[0] = td->dummy_sock; | ||||
|       return GETSOCK_READSOCK(0); | ||||
|     } | ||||
|   } | ||||
|   (void)conn; | ||||
|   (void)socks; | ||||
|   (void)numsocks; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -696,4 +673,13 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, | ||||
|  | ||||
| #endif /* !HAVE_GETADDRINFO */ | ||||
|  | ||||
| CURLcode Curl_set_dns_servers(struct SessionHandle *data, | ||||
|                               char *servers) | ||||
| { | ||||
|   (void)data; | ||||
|   (void)servers; | ||||
|   return CURLE_NOT_BUILT_IN; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif /* CURLRES_THREADED */ | ||||
|   | ||||
| @@ -653,10 +653,10 @@ | ||||
| #undef OS | ||||
| #if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */ | ||||
| #define OS "i386-pc-win32" | ||||
| #elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */ | ||||
| #define OS "x86_64-pc-win32" | ||||
| #elif defined(_M_IA64) /* Itanium */ | ||||
| #define OS "ia64-pc-win32" | ||||
| #elif defined(_M_X64) /* AMD64/EM64T - Not defined until MSVC 2005 */ | ||||
| #define OS "amd64-pc-win32" | ||||
| #else | ||||
| #define OS "unknown-pc-win32" | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										178
									
								
								lib/connect.c
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								lib/connect.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -89,18 +89,6 @@ | ||||
| #undef SO_NOSIGPIPE | ||||
| #endif | ||||
|  | ||||
| struct Curl_sockaddr_ex { | ||||
|   int family; | ||||
|   int socktype; | ||||
|   int protocol; | ||||
|   unsigned int addrlen; | ||||
|   union { | ||||
|     struct sockaddr addr; | ||||
|     struct Curl_sockaddr_storage buff; | ||||
|   } _sa_ex_u; | ||||
| }; | ||||
| #define sa_addr _sa_ex_u.addr | ||||
|  | ||||
| static bool verifyconnect(curl_socket_t sockfd, int *error); | ||||
|  | ||||
| static CURLcode | ||||
| @@ -252,6 +240,10 @@ static CURLcode bindlocal(struct connectdata *conn, | ||||
|   int error; | ||||
|   char myhost[256] = ""; | ||||
|   int done = 0; /* -1 for error, 1 for address found */ | ||||
|   bool is_interface = FALSE; | ||||
|   bool is_host = FALSE; | ||||
|   static const char *if_prefix = "if!"; | ||||
|   static const char *host_prefix = "host!"; | ||||
|  | ||||
|   /************************************************************* | ||||
|    * Select device to bind socket to | ||||
| @@ -263,9 +255,20 @@ static CURLcode bindlocal(struct connectdata *conn, | ||||
|   memset(&sa, 0, sizeof(struct Curl_sockaddr_storage)); | ||||
|  | ||||
|   if(dev && (strlen(dev)<255) ) { | ||||
|     if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) { | ||||
|       dev += strlen(if_prefix); | ||||
|       is_interface = TRUE; | ||||
|     } | ||||
|     else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) { | ||||
|       dev += strlen(host_prefix); | ||||
|       is_host = TRUE; | ||||
|     } | ||||
|  | ||||
|     /* interface */ | ||||
|     if(Curl_if2ip(af, dev, myhost, sizeof(myhost))) { | ||||
|     if(!is_host && (is_interface || Curl_if_is_interface_name(dev))) { | ||||
|       if(Curl_if2ip(af, dev, myhost, sizeof(myhost)) == NULL) | ||||
|         return CURLE_INTERFACE_FAILED; | ||||
|  | ||||
|       /* | ||||
|        * We now have the numerical IP address in the 'myhost' buffer | ||||
|        */ | ||||
| @@ -836,61 +839,18 @@ singleipconnect(struct connectdata *conn, | ||||
| { | ||||
|   struct Curl_sockaddr_ex addr; | ||||
|   int rc; | ||||
|   int error; | ||||
|   int error = 0; | ||||
|   bool isconnected = FALSE; | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   curl_socket_t sockfd; | ||||
|   CURLcode res = CURLE_OK; | ||||
| #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) | ||||
|   struct sockaddr_in6 * const sa6 = (void *)&addr.sa_addr; | ||||
| #endif | ||||
|  | ||||
|   *sockp = CURL_SOCKET_BAD; | ||||
|  | ||||
|   /* | ||||
|    * The Curl_sockaddr_ex structure is basically libcurl's external API | ||||
|    * curl_sockaddr structure with enough space available to directly hold | ||||
|    * any protocol-specific address structures. The variable declared here | ||||
|    * will be used to pass / receive data to/from the fopensocket callback | ||||
|    * if this has been set, before that, it is initialized from parameters. | ||||
|    */ | ||||
|  | ||||
|   addr.family = ai->ai_family; | ||||
|   addr.socktype = conn->socktype; | ||||
|   addr.protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol; | ||||
|   addr.addrlen = ai->ai_addrlen; | ||||
|  | ||||
|   if(addr.addrlen > sizeof(struct Curl_sockaddr_storage)) | ||||
|      addr.addrlen = sizeof(struct Curl_sockaddr_storage); | ||||
|   memcpy(&addr.sa_addr, ai->ai_addr, addr.addrlen); | ||||
|  | ||||
|   *connected = FALSE; /* default is not connected */ | ||||
|  | ||||
|   if(data->set.fopensocket) | ||||
|    /* | ||||
|     * If the opensocket callback is set, all the destination address | ||||
|     * information is passed to the callback. Depending on this information the | ||||
|     * callback may opt to abort the connection, this is indicated returning | ||||
|     * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When | ||||
|     * the callback returns a valid socket the destination address information | ||||
|     * might have been changed and this 'new' address will actually be used | ||||
|     * here to connect. | ||||
|     */ | ||||
|     sockfd = data->set.fopensocket(data->set.opensocket_client, | ||||
|                                    CURLSOCKTYPE_IPCXN, | ||||
|                                    (struct curl_sockaddr *)&addr); | ||||
|   else | ||||
|     /* opensocket callback not set, so simply create the socket now */ | ||||
|     sockfd = socket(addr.family, addr.socktype, addr.protocol); | ||||
|  | ||||
|   if(sockfd == CURL_SOCKET_BAD) | ||||
|     /* no socket, no connection */ | ||||
|     return CURLE_OK; | ||||
|  | ||||
| #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) | ||||
|   if(conn->scope && (addr.family == AF_INET6)) | ||||
|     sa6->sin6_scope_id = conn->scope; | ||||
| #endif | ||||
|   res = Curl_socket(conn, ai, &addr, &sockfd); | ||||
|   if(res) | ||||
|     return res; | ||||
|  | ||||
|   /* store remote address and port used in this connection attempt */ | ||||
|   if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, | ||||
| @@ -903,15 +863,10 @@ singleipconnect(struct connectdata *conn, | ||||
|     return CURLE_OK; | ||||
|   } | ||||
|   memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); | ||||
|   infof(data, "  Trying %s... ", conn->ip_addr_str); | ||||
|   infof(data, "  Trying %s...\n", conn->ip_addr_str); | ||||
|  | ||||
|   Curl_persistconninfo(conn); | ||||
|  | ||||
| #ifdef ENABLE_IPV6 | ||||
|   if(addr.family == AF_INET6) | ||||
|     conn->bits.ipv6 = TRUE; | ||||
| #endif | ||||
|  | ||||
|   if(data->set.tcp_nodelay) | ||||
|     tcpnodelay(conn, sockfd); | ||||
|  | ||||
| @@ -946,6 +901,8 @@ singleipconnect(struct connectdata *conn, | ||||
|   /* Connect TCP sockets, bind UDP */ | ||||
|   if(!isconnected && (conn->socktype == SOCK_STREAM)) { | ||||
|     rc = connect(sockfd, &addr.sa_addr, addr.addrlen); | ||||
|     if(-1 == rc) | ||||
|       error = SOCKERRNO; | ||||
|     conn->connecttime = Curl_tvnow(); | ||||
|     if(conn->num_addr > 1) | ||||
|       Curl_expire(data, conn->timeoutms_per_addr); | ||||
| @@ -954,8 +911,6 @@ singleipconnect(struct connectdata *conn, | ||||
|     rc = 0; | ||||
|  | ||||
|   if(-1 == rc) { | ||||
|     error = SOCKERRNO; | ||||
|  | ||||
|     switch (error) { | ||||
|     case EINPROGRESS: | ||||
|     case EWOULDBLOCK: | ||||
| @@ -999,6 +954,10 @@ singleipconnect(struct connectdata *conn, | ||||
|     /* we are connected, awesome! */ | ||||
|     *connected = TRUE; /* this is a true connect */ | ||||
|     infof(data, "connected\n"); | ||||
| #ifdef ENABLE_IPV6 | ||||
|     conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE; | ||||
| #endif | ||||
|  | ||||
|     Curl_updateconninfo(conn, sockfd); | ||||
|     *sockp = sockfd; | ||||
|     return CURLE_OK; | ||||
| @@ -1166,8 +1125,85 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data, | ||||
| int Curl_closesocket(struct connectdata *conn, | ||||
|                      curl_socket_t sock) | ||||
| { | ||||
|   if(conn && conn->fclosesocket) | ||||
|     return conn->fclosesocket(conn->closesocket_client, sock); | ||||
|   if(conn && conn->fclosesocket) { | ||||
|     if((sock == conn->sock[SECONDARYSOCKET]) && | ||||
|        conn->sock_accepted[SECONDARYSOCKET]) | ||||
|       /* if this socket matches the second socket, and that was created with | ||||
|          accept, then we MUST NOT call the callback but clear the accepted | ||||
|          status */ | ||||
|       conn->sock_accepted[SECONDARYSOCKET] = FALSE; | ||||
|     else | ||||
|       return conn->fclosesocket(conn->closesocket_client, sock); | ||||
|   } | ||||
|   return sclose(sock); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Create a socket based on info from 'conn' and 'ai'. | ||||
|  * | ||||
|  * 'addr' should be a pointer to the correct struct to get data back, or NULL. | ||||
|  * 'sockfd' must be a pointer to a socket descriptor. | ||||
|  * | ||||
|  * If the open socket callback is set, used that! | ||||
|  * | ||||
|  */ | ||||
| CURLcode Curl_socket(struct connectdata *conn, | ||||
|                      const Curl_addrinfo *ai, | ||||
|                      struct Curl_sockaddr_ex *addr, | ||||
|                      curl_socket_t *sockfd) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   struct Curl_sockaddr_ex dummy; | ||||
|  | ||||
|   if(!addr) | ||||
|     /* if the caller doesn't want info back, use a local temp copy */ | ||||
|     addr = &dummy; | ||||
|  | ||||
|   /* | ||||
|    * The Curl_sockaddr_ex structure is basically libcurl's external API | ||||
|    * curl_sockaddr structure with enough space available to directly hold | ||||
|    * any protocol-specific address structures. The variable declared here | ||||
|    * will be used to pass / receive data to/from the fopensocket callback | ||||
|    * if this has been set, before that, it is initialized from parameters. | ||||
|    */ | ||||
|  | ||||
|   addr->family = ai->ai_family; | ||||
|   addr->socktype = conn->socktype; | ||||
|   addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol; | ||||
|   addr->addrlen = ai->ai_addrlen; | ||||
|  | ||||
|   if(addr->addrlen > sizeof(struct Curl_sockaddr_storage)) | ||||
|      addr->addrlen = sizeof(struct Curl_sockaddr_storage); | ||||
|   memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen); | ||||
|  | ||||
|   if(data->set.fopensocket) | ||||
|    /* | ||||
|     * If the opensocket callback is set, all the destination address | ||||
|     * information is passed to the callback. Depending on this information the | ||||
|     * callback may opt to abort the connection, this is indicated returning | ||||
|     * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When | ||||
|     * the callback returns a valid socket the destination address information | ||||
|     * might have been changed and this 'new' address will actually be used | ||||
|     * here to connect. | ||||
|     */ | ||||
|     *sockfd = data->set.fopensocket(data->set.opensocket_client, | ||||
|                                     CURLSOCKTYPE_IPCXN, | ||||
|                                     (struct curl_sockaddr *)addr); | ||||
|   else | ||||
|     /* opensocket callback not set, so simply create the socket now */ | ||||
|     *sockfd = socket(addr->family, addr->socktype, addr->protocol); | ||||
|  | ||||
|   if(*sockfd == CURL_SOCKET_BAD) | ||||
|     /* no socket, no connection */ | ||||
|     return CURLE_FAILED_INIT; | ||||
|  | ||||
| #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) | ||||
|   if(conn->scope && (addr->family == AF_INET6)) { | ||||
|     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr; | ||||
|     sa6->sin6_scope_id = conn->scope; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   return CURLE_OK; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
| #include "setup.h" | ||||
|  | ||||
| #include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */ | ||||
| #include "sockaddr.h" | ||||
|  | ||||
| CURLcode Curl_is_connected(struct connectdata *conn, | ||||
|                            int sockindex, | ||||
| @@ -72,4 +73,35 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd); | ||||
| void Curl_persistconninfo(struct connectdata *conn); | ||||
| int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); | ||||
|  | ||||
| /* | ||||
|  * The Curl_sockaddr_ex structure is basically libcurl's external API | ||||
|  * curl_sockaddr structure with enough space available to directly hold any | ||||
|  * protocol-specific address structures. The variable declared here will be | ||||
|  * used to pass / receive data to/from the fopensocket callback if this has | ||||
|  * been set, before that, it is initialized from parameters. | ||||
|  */ | ||||
| struct Curl_sockaddr_ex { | ||||
|   int family; | ||||
|   int socktype; | ||||
|   int protocol; | ||||
|   unsigned int addrlen; | ||||
|   union { | ||||
|     struct sockaddr addr; | ||||
|     struct Curl_sockaddr_storage buff; | ||||
|   } _sa_ex_u; | ||||
| }; | ||||
| #define sa_addr _sa_ex_u.addr | ||||
|  | ||||
| /* | ||||
|  * Create a socket based on info from 'conn' and 'ai'. | ||||
|  * | ||||
|  * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open | ||||
|  * socket callback is set, used that! | ||||
|  * | ||||
|  */ | ||||
| CURLcode Curl_socket(struct connectdata *conn, | ||||
|                      const Curl_addrinfo *ai, | ||||
|                      struct Curl_sockaddr_ex *addr, | ||||
|                      curl_socket_t *sockfd); | ||||
|  | ||||
| #endif /* HEADER_CURL_CONNECT_H */ | ||||
|   | ||||
							
								
								
									
										21
									
								
								lib/cookie.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								lib/cookie.c
									
									
									
									
									
								
							| @@ -144,9 +144,9 @@ void Curl_cookie_loadfiles(struct SessionHandle *data) | ||||
|                                        data->set.cookiesession); | ||||
|       list = list->next; | ||||
|     } | ||||
|     Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); | ||||
|     curl_slist_free_all(data->change.cookielist); /* clean up list */ | ||||
|     data->change.cookielist = NULL; /* don't do this again! */ | ||||
|     Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -1107,23 +1107,20 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data) | ||||
|  | ||||
|   c = data->cookies->cookies; | ||||
|  | ||||
|   beg = list; | ||||
|   while(c) { | ||||
|     /* fill the list with _all_ the cookies we know */ | ||||
|     line = get_netscape_format(c); | ||||
|     if(line == NULL) { | ||||
|       curl_slist_free_all(beg); | ||||
|     if(!line) { | ||||
|       curl_slist_free_all(list); | ||||
|       return NULL; | ||||
|     } | ||||
|     list = curl_slist_append(list, line); | ||||
|     beg = curl_slist_append(list, line); | ||||
|     free(line); | ||||
|     if(list == NULL) { | ||||
|       curl_slist_free_all(beg); | ||||
|     if(!beg) { | ||||
|       curl_slist_free_all(list); | ||||
|       return NULL; | ||||
|     } | ||||
|     else if(beg == NULL) { | ||||
|       beg = list; | ||||
|     } | ||||
|     list = beg; | ||||
|     c = c->next; | ||||
|   } | ||||
|  | ||||
| @@ -1148,10 +1145,12 @@ void Curl_flush_cookies(struct SessionHandle *data, int cleanup) | ||||
|             data->set.str[STRING_COOKIEJAR]); | ||||
|   } | ||||
|   else { | ||||
|     if(cleanup && data->change.cookielist) | ||||
|     if(cleanup && data->change.cookielist) { | ||||
|       /* since nothing is written, we can just free the list of cookie file | ||||
|          names */ | ||||
|       curl_slist_free_all(data->change.cookielist); /* clean up list */ | ||||
|       data->change.cookielist = NULL; | ||||
|     } | ||||
|     Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -32,12 +32,16 @@ | ||||
|  * Curl_gethostname() is a wrapper around gethostname() which allows | ||||
|  * overriding the host name that the function would normally return. | ||||
|  * This capability is used by the test suite to verify exact matching | ||||
|  * of NTLM authentication, which exercises libcurl's MD4 and DES code. | ||||
|  * of NTLM authentication, which exercises libcurl's MD4 and DES code | ||||
|  * as well as by the SMTP module when a hostname is not provided. | ||||
|  * | ||||
|  * For libcurl debug enabled builds host name overriding takes place | ||||
|  * when environment variable CURL_GETHOSTNAME is set, using the value | ||||
|  * held by the variable to override returned host name. | ||||
|  * | ||||
|  * Note: The function always returns the un-qualified hostname rather | ||||
|  * than being provider dependent. | ||||
|  * | ||||
|  * For libcurl shared library release builds the test suite preloads | ||||
|  * another shared library named libhostname using the LD_PRELOAD | ||||
|  * mechanism which intercepts, and might override, the gethostname() | ||||
| @@ -58,6 +62,8 @@ int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) { | ||||
|   return -1; | ||||
|  | ||||
| #else | ||||
|   int err; | ||||
|   char* dot; | ||||
|  | ||||
| #ifdef DEBUGBUILD | ||||
|  | ||||
| @@ -65,17 +71,34 @@ int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) { | ||||
|   const char *force_hostname = getenv("CURL_GETHOSTNAME"); | ||||
|   if(force_hostname) { | ||||
|     strncpy(name, force_hostname, namelen); | ||||
|     name[namelen-1] = '\0'; | ||||
|     return 0; | ||||
|     err = 0; | ||||
|   } | ||||
|   else { | ||||
|     name[0] = '\0'; | ||||
|     err = gethostname(name, namelen); | ||||
|   } | ||||
|  | ||||
| #endif /* DEBUGBUILD */ | ||||
| #else /* DEBUGBUILD */ | ||||
|  | ||||
|   /* The call to system's gethostname() might get intercepted by the | ||||
|      libhostname library when libcurl is built as a non-debug shared | ||||
|      library when running the test suite. */ | ||||
|   return gethostname(name, namelen); | ||||
|   name[0] = '\0'; | ||||
|   err = gethostname(name, namelen); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   name[namelen - 1] = '\0'; | ||||
|  | ||||
|   if(err) | ||||
|     return err; | ||||
|  | ||||
|   /* Truncate domain, leave only machine name */ | ||||
|   dot = strchr(name, '.'); | ||||
|   if(dot) | ||||
|     *dot = '\0'; | ||||
|  | ||||
|   return 0; | ||||
| #endif | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,10 @@ | ||||
|  * | ||||
|  ***************************************************************************/ | ||||
|  | ||||
| /* Hostname buffer size */ | ||||
| #define HOSTNAME_MAX 1024 | ||||
|  | ||||
| /* This returns the local machine's un-qualified hostname */ | ||||
| int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen); | ||||
|  | ||||
| #endif /* HEADER_CURL_GETHOSTNAME_H */ | ||||
|   | ||||
| @@ -114,6 +114,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, | ||||
|                           bool proxy) | ||||
| { | ||||
|   char *base64 = NULL; | ||||
|   size_t len = 0; | ||||
|   CURLcode error; | ||||
|  | ||||
|   /* point to the address of the pointer that holds the string to send to the | ||||
| @@ -172,7 +173,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, | ||||
|   case NTLMSTATE_TYPE1: | ||||
|   default: /* for the weird cases we (re)start here */ | ||||
|     /* Create a type-1 message */ | ||||
|     error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64); | ||||
|     error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64, | ||||
|                                            &len); | ||||
|  | ||||
|     if(error) | ||||
|       return error; | ||||
|  | ||||
| @@ -189,7 +192,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, | ||||
|   case NTLMSTATE_TYPE2: | ||||
|     /* We already received the type-2 message, create a type-3 message */ | ||||
|     error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp, | ||||
|                                            ntlm, &base64); | ||||
|                                            ntlm, &base64, &len); | ||||
|     if(error) | ||||
|       return error; | ||||
|  | ||||
|   | ||||
| @@ -63,6 +63,11 @@ | ||||
| #    define DESKEY(x) &x | ||||
| #  endif | ||||
|  | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|  | ||||
| #  include <nettle/des.h> | ||||
| #  include <nettle/md4.h> | ||||
|  | ||||
| #elif defined(USE_GNUTLS) | ||||
|  | ||||
| #  include <gcrypt.h> | ||||
| @@ -133,7 +138,17 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key) | ||||
|   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF); | ||||
| } | ||||
|  | ||||
| #if defined(USE_GNUTLS) | ||||
| #if defined(USE_GNUTLS_NETTLE) | ||||
|  | ||||
| static void setup_des_key(const unsigned char *key_56, | ||||
|                           struct des_ctx *des) | ||||
| { | ||||
|   char key[8]; | ||||
|   extend_key_56_to_64(key_56, key); | ||||
|   des_set_key(des, key); | ||||
| } | ||||
|  | ||||
| #elif defined(USE_GNUTLS) | ||||
|  | ||||
| /* | ||||
|  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. | ||||
| @@ -233,6 +248,14 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, | ||||
|   setup_des_key(keys + 14, DESKEY(ks)); | ||||
|   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16), | ||||
|                   DESKEY(ks), DES_ENCRYPT); | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|   struct des_ctx des; | ||||
|   setup_des_key(keys, &des); | ||||
|   des_encrypt(&des, 8, results, plaintext); | ||||
|   setup_des_key(keys + 7, &des); | ||||
|   des_encrypt(&des, 8, results + 8, plaintext); | ||||
|   setup_des_key(keys + 14, &des); | ||||
|   des_encrypt(&des, 8, results + 16, plaintext); | ||||
| #elif defined(USE_GNUTLS) | ||||
|   gcry_cipher_hd_t des; | ||||
|  | ||||
| @@ -295,6 +318,12 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data, | ||||
|     setup_des_key(pw + 7, DESKEY(ks)); | ||||
|     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8), | ||||
|                     DESKEY(ks), DES_ENCRYPT); | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|     struct des_ctx des; | ||||
|     setup_des_key(pw, &des); | ||||
|     des_encrypt(&des, 8, lmbuffer, magic); | ||||
|     setup_des_key(pw + 7, &des); | ||||
|     des_encrypt(&des, 8, lmbuffer + 8, magic); | ||||
| #elif defined(USE_GNUTLS) | ||||
|     gcry_cipher_hd_t des; | ||||
|  | ||||
| @@ -357,6 +386,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, | ||||
|     MD4_Init(&MD4pw); | ||||
|     MD4_Update(&MD4pw, pw, 2 * len); | ||||
|     MD4_Final(ntbuffer, &MD4pw); | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|     struct md4_ctx MD4pw; | ||||
|     md4_init(&MD4pw); | ||||
|     md4_update(&MD4pw, 2 * len, pw); | ||||
|     md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer); | ||||
| #elif defined(USE_GNUTLS) | ||||
|     gcry_md_hd_t MD4pw; | ||||
|     gcry_md_open(&MD4pw, GCRY_MD_MD4, 0); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -54,6 +54,13 @@ | ||||
| #  endif | ||||
| #  include "ssluse.h" | ||||
|  | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|  | ||||
| #  include <nettle/md5.h> | ||||
| #  include <gnutls/gnutls.h> | ||||
| #  include <gnutls/crypto.h> | ||||
| #  define MD5_DIGEST_LENGTH 16 | ||||
|  | ||||
| #elif defined(USE_GNUTLS) | ||||
|  | ||||
| #  include <gcrypt.h> | ||||
| @@ -93,9 +100,6 @@ | ||||
| /* The last #include file should be: */ | ||||
| #include "memdebug.h" | ||||
|  | ||||
| /* Hostname buffer size */ | ||||
| #define HOSTNAME_MAX 1024 | ||||
|  | ||||
| /* "NTLMSSP" signature is always in ASCII regardless of the platform */ | ||||
| #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" | ||||
|  | ||||
| @@ -357,13 +361,15 @@ static void unicodecpy(unsigned char *dest, | ||||
|  * ntlm    [in/out] - The ntlm data struct being used and modified. | ||||
|  * outptr  [in/out] - The adress where a pointer to newly allocated memory | ||||
|  *                    holding the result will be stored upon completion. | ||||
|  * outlen  [out]    - The length of the output message. | ||||
|  * | ||||
|  * Returns CURLE_OK on success. | ||||
|  */ | ||||
| CURLcode Curl_ntlm_create_type1_message(const char *userp, | ||||
|                                         const char *passwdp, | ||||
|                                         struct ntlmdata *ntlm, | ||||
|                                         char **outptr) | ||||
|                                         char **outptr, | ||||
|                                         size_t *outlen) | ||||
| { | ||||
|   /* NTLM type-1 message structure: | ||||
|  | ||||
| @@ -380,7 +386,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, | ||||
|   */ | ||||
|  | ||||
|   unsigned char ntlmbuf[NTLM_BUFSIZE]; | ||||
|   size_t base64_sz = 0; | ||||
|   size_t size; | ||||
|  | ||||
| #ifdef USE_WINDOWS_SSPI | ||||
| @@ -559,7 +564,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, | ||||
|   }); | ||||
|  | ||||
|   /* Return with binary blob encoded into base64 */ | ||||
|   return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz); | ||||
|   return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -577,6 +582,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, | ||||
|  * ntlm    [in/out] - The ntlm data struct being used and modified. | ||||
|  * outptr  [in/out] - The adress where a pointer to newly allocated memory | ||||
|  *                    holding the result will be stored upon completion. | ||||
|  * outlen  [out]    - The length of the output message. | ||||
|  * | ||||
|  * Returns CURLE_OK on success. | ||||
|  */ | ||||
| @@ -584,7 +590,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
|                                         const char *userp, | ||||
|                                         const char *passwdp, | ||||
|                                         struct ntlmdata *ntlm, | ||||
|                                         char **outptr) | ||||
|                                         char **outptr, | ||||
|                                         size_t *outlen) | ||||
| { | ||||
|   /* NTLM type-3 message structure: | ||||
|  | ||||
| @@ -605,7 +612,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
|   */ | ||||
|  | ||||
|   unsigned char ntlmbuf[NTLM_BUFSIZE]; | ||||
|   size_t base64_sz = 0; | ||||
|   size_t size; | ||||
|  | ||||
| #ifdef USE_WINDOWS_SSPI | ||||
| @@ -686,18 +692,13 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
|   if(user) | ||||
|     userlen = strlen(user); | ||||
|  | ||||
|   if(Curl_gethostname(host, HOSTNAME_MAX)) { | ||||
|     infof(data, "gethostname() failed, continuing without!"); | ||||
|   /* Get the machine's un-qualified host name as NTLM doesn't like the fully | ||||
|      qualified domain name */ | ||||
|   if(Curl_gethostname(host, sizeof(host))) { | ||||
|     infof(data, "gethostname() failed, continuing without!\n"); | ||||
|     hostlen = 0; | ||||
|   } | ||||
|   else { | ||||
|     /* If the workstation if configured with a full DNS name (i.e. | ||||
|      * workstation.somewhere.net) gethostname() returns the fully qualified | ||||
|      * name, which NTLM doesn't like. | ||||
|      */ | ||||
|     char *dot = strchr(host, '.'); | ||||
|     if(dot) | ||||
|       *dot = '\0'; | ||||
|     hostlen = strlen(host); | ||||
|   } | ||||
|  | ||||
| @@ -720,13 +721,16 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
|     MD5_CTX MD5pw; | ||||
|     Curl_ossl_seed(data); /* Initiate the seed if not already done */ | ||||
|     RAND_bytes(entropy, 8); | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|     struct md5_ctx MD5pw; | ||||
|     gnutls_rnd(GNUTLS_RND_RANDOM, entropy, 8); | ||||
| #elif defined(USE_GNUTLS) | ||||
|     gcry_md_hd_t MD5pw; | ||||
|     Curl_gtls_seed(data); /* Initiate the seed if not already done */ | ||||
|     gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM); | ||||
| #elif defined(USE_NSS) | ||||
|     PK11Context *MD5pw; | ||||
|     unsigned int outlen; | ||||
|     unsigned int MD5len; | ||||
|     Curl_nss_seed(data);  /* Initiate the seed if not already done */ | ||||
|     PK11_GenerateRandom(entropy, 8); | ||||
| #endif | ||||
| @@ -745,6 +749,10 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
|     MD5_Init(&MD5pw); | ||||
|     MD5_Update(&MD5pw, tmp, 16); | ||||
|     MD5_Final(md5sum, &MD5pw); | ||||
| #elif defined(USE_GNUTLS_NETTLE) | ||||
|     md5_init(&MD5pw); | ||||
|     md5_update(&MD5pw, 16, tmp); | ||||
|     md5_digest(&MD5pw, 16, md5sum); | ||||
| #elif defined(USE_GNUTLS) | ||||
|     gcry_md_open(&MD5pw, GCRY_MD_MD5, 0); | ||||
|     gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH); | ||||
| @@ -753,7 +761,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
| #elif defined(USE_NSS) | ||||
|     MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); | ||||
|     PK11_DigestOp(MD5pw, tmp, 16); | ||||
|     PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH); | ||||
|     PK11_DigestFinal(MD5pw, md5sum, &MD5len, MD5_DIGEST_LENGTH); | ||||
|     PK11_DestroyContext(MD5pw, PR_TRUE); | ||||
| #endif | ||||
|  | ||||
| @@ -958,7 +966,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
| #endif | ||||
|  | ||||
|   /* Return with binary blob encoded into base64 */ | ||||
|   return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz); | ||||
|   return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); | ||||
| } | ||||
|  | ||||
| #endif /* USE_NTLM */ | ||||
|   | ||||
| @@ -30,14 +30,16 @@ | ||||
| CURLcode Curl_ntlm_create_type1_message(const char *userp, | ||||
|                                         const char *passwdp, | ||||
|                                         struct ntlmdata *ntlm, | ||||
|                                         char **outptr); | ||||
|                                         char **outptr, | ||||
|                                         size_t *outlen); | ||||
|  | ||||
| /* This is to generate a base64 encoded NTLM type-3 message */ | ||||
| CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, | ||||
|                                         const char *userp, | ||||
|                                         const char *passwdp, | ||||
|                                         struct ntlmdata *ntlm, | ||||
|                                         char **outptr); | ||||
|                                         char **outptr, | ||||
|                                         size_t *outlen); | ||||
|  | ||||
| /* This is to decode a NTLM type-2 message */ | ||||
| CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data, | ||||
| @@ -47,6 +49,8 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data, | ||||
| /* This is to clean up the ntlm data structure */ | ||||
| #ifdef USE_WINDOWS_SSPI | ||||
| void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm); | ||||
| #else | ||||
| #define Curl_ntlm_sspi_cleanup(x) | ||||
| #endif | ||||
|  | ||||
| /* NTLM buffer fixed size, large enough for long user + host + domain */ | ||||
|   | ||||
| @@ -71,6 +71,7 @@ const struct Curl_handler Curl_handler_rtmp = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   rtmp_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -90,6 +91,7 @@ const struct Curl_handler Curl_handler_rtmpt = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   rtmp_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -109,6 +111,7 @@ const struct Curl_handler Curl_handler_rtmpe = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   rtmp_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -128,6 +131,7 @@ const struct Curl_handler Curl_handler_rtmpte = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   rtmp_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -147,6 +151,7 @@ const struct Curl_handler Curl_handler_rtmps = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   rtmp_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -166,6 +171,7 @@ const struct Curl_handler Curl_handler_rtmpts = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   rtmp_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -258,7 +258,7 @@ cyassl_connect_step2(struct connectdata *conn, | ||||
|   } | ||||
|  | ||||
|   conssl->connecting_state = ssl_connect_3; | ||||
|   infof(data, "SSL connected"); | ||||
|   infof(data, "SSL connected\n"); | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
| @@ -404,7 +404,12 @@ size_t Curl_cyassl_version(char *buffer, size_t size) | ||||
|  | ||||
| int Curl_cyassl_init(void) | ||||
| { | ||||
| #if (LIBCYASSL_VERSION_HEX >= 0x02000000) | ||||
|   if(SSL_library_init() != SSL_SUCCESS) | ||||
|     return 0; | ||||
| #else | ||||
|   InitCyaSSL(); | ||||
| #endif | ||||
|  | ||||
|   return 1; | ||||
| } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -92,12 +92,13 @@ const struct Curl_handler Curl_handler_dict = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
|   PORT_DICT,                            /* defport */ | ||||
|   CURLPROTO_DICT,                       /* protocol */ | ||||
|   PROTOPT_NONE                          /* flags */ | ||||
|   PROTOPT_NONE | PROTOPT_NOURLQUERY      /* flags */ | ||||
| }; | ||||
|  | ||||
| static char *unescape_word(struct SessionHandle *data, const char *inputbuff) | ||||
| @@ -177,7 +178,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) | ||||
|     } | ||||
|  | ||||
|     if((word == NULL) || (*word == (char)0)) { | ||||
|       infof(data, "lookup word is missing"); | ||||
|       infof(data, "lookup word is missing\n"); | ||||
|       word=(char *)"default"; | ||||
|     } | ||||
|     if((database == NULL) || (*database == (char)0)) { | ||||
| @@ -231,7 +232,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) | ||||
|     } | ||||
|  | ||||
|     if((word == NULL) || (*word == (char)0)) { | ||||
|       infof(data, "lookup word is missing"); | ||||
|       infof(data, "lookup word is missing\n"); | ||||
|       word=(char *)"default"; | ||||
|     } | ||||
|     if((database == NULL) || (*database == (char)0)) { | ||||
|   | ||||
							
								
								
									
										19
									
								
								lib/easy.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib/easy.c
									
									
									
									
									
								
							| @@ -676,16 +676,15 @@ CURL *curl_easy_duphandle(CURL *incurl) | ||||
|  | ||||
|   if(outcurl) { | ||||
|     if(outcurl->state.connc && | ||||
|        (outcurl->state.connc->type == CONNCACHE_PRIVATE)) | ||||
|        (outcurl->state.connc->type == CONNCACHE_PRIVATE)) { | ||||
|       Curl_rm_connc(outcurl->state.connc); | ||||
|     if(outcurl->state.headerbuff) | ||||
|       free(outcurl->state.headerbuff); | ||||
|     if(outcurl->change.cookielist) | ||||
|       outcurl->state.connc = NULL; | ||||
|     } | ||||
|     curl_slist_free_all(outcurl->change.cookielist); | ||||
|     if(outcurl->change.url) | ||||
|       free(outcurl->change.url); | ||||
|     if(outcurl->change.referer) | ||||
|       free(outcurl->change.referer); | ||||
|     outcurl->change.cookielist = NULL; | ||||
|     Curl_safefree(outcurl->state.headerbuff); | ||||
|     Curl_safefree(outcurl->change.url); | ||||
|     Curl_safefree(outcurl->change.referer); | ||||
|     Curl_freeset(outcurl); | ||||
|     free(outcurl); | ||||
|   } | ||||
| @@ -702,10 +701,10 @@ void curl_easy_reset(CURL *curl) | ||||
|   struct SessionHandle *data = (struct SessionHandle *)curl; | ||||
|  | ||||
|   Curl_safefree(data->state.pathbuffer); | ||||
|   data->state.pathbuffer=NULL; | ||||
|  | ||||
|   data->state.path = NULL; | ||||
|  | ||||
|   Curl_safefree(data->state.proto.generic); | ||||
|   data->state.proto.generic=NULL; | ||||
|  | ||||
|   /* zero out UserDefined data: */ | ||||
|   Curl_freeset(data); | ||||
|   | ||||
							
								
								
									
										63
									
								
								lib/escape.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								lib/escape.c
									
									
									
									
									
								
							| @@ -31,6 +31,7 @@ | ||||
| #include "urldata.h" | ||||
| #include "warnless.h" | ||||
| #include "non-ascii.h" | ||||
| #include "escape.h" | ||||
|  | ||||
| #define _MPRINTF_REPLACE /* use our functions only */ | ||||
| #include <curl/mprintf.h> | ||||
| @@ -84,7 +85,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength) | ||||
|   char *testing_ptr = NULL; | ||||
|   unsigned char in; /* we need to treat the characters unsigned */ | ||||
|   size_t newlen = alloc; | ||||
|   int strindex=0; | ||||
|   size_t strindex=0; | ||||
|   size_t length; | ||||
|   CURLcode res; | ||||
|  | ||||
| @@ -132,23 +133,29 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength) | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Unescapes the given URL escaped string of given length. Returns a | ||||
|  * pointer to a malloced string with length given in *olen. | ||||
|  * If length == 0, the length is assumed to be strlen(string). | ||||
|  * If olen == NULL, no output length is stored. | ||||
|  * Curl_urldecode() URL decodes the given string. | ||||
|  * | ||||
|  * Optionally detects control characters (byte codes lower than 32) in the | ||||
|  * data and rejects such data. | ||||
|  * | ||||
|  * Returns a pointer to a malloced string in *ostring with length given in | ||||
|  * *olen. If length == 0, the length is assumed to be strlen(string). | ||||
|  * | ||||
|  */ | ||||
| char *curl_easy_unescape(CURL *handle, const char *string, int length, | ||||
|                          int *olen) | ||||
| CURLcode Curl_urldecode(struct SessionHandle *data, | ||||
|                         const char *string, size_t length, | ||||
|                         char **ostring, size_t *olen, | ||||
|                         bool reject_ctrl) | ||||
| { | ||||
|   int alloc = (length?length:(int)strlen(string))+1; | ||||
|   size_t alloc = (length?length:strlen(string))+1; | ||||
|   char *ns = malloc(alloc); | ||||
|   unsigned char in; | ||||
|   int strindex=0; | ||||
|   size_t strindex=0; | ||||
|   unsigned long hex; | ||||
|   CURLcode res; | ||||
|  | ||||
|   if(!ns) | ||||
|     return NULL; | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
|   while(--alloc > 0) { | ||||
|     in = *string; | ||||
| @@ -164,16 +171,20 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length, | ||||
|  | ||||
|       in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ | ||||
|  | ||||
|       res = Curl_convert_from_network(handle, &in, 1); | ||||
|       res = Curl_convert_from_network(data, &in, 1); | ||||
|       if(res) { | ||||
|         /* Curl_convert_from_network calls failf if unsuccessful */ | ||||
|         free(ns); | ||||
|         return NULL; | ||||
|         return res; | ||||
|       } | ||||
|  | ||||
|       string+=2; | ||||
|       alloc-=2; | ||||
|     } | ||||
|     if(reject_ctrl && (in < 0x20)) { | ||||
|       free(ns); | ||||
|       return CURLE_URL_MALFORMAT; | ||||
|     } | ||||
|  | ||||
|     ns[strindex++] = in; | ||||
|     string++; | ||||
| @@ -183,7 +194,33 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length, | ||||
|   if(olen) | ||||
|     /* store output size */ | ||||
|     *olen = strindex; | ||||
|   return ns; | ||||
|  | ||||
|   if(ostring) | ||||
|     /* store output string */ | ||||
|     *ostring = ns; | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Unescapes the given URL escaped string of given length. Returns a | ||||
|  * pointer to a malloced string with length given in *olen. | ||||
|  * If length == 0, the length is assumed to be strlen(string). | ||||
|  * If olen == NULL, no output length is stored. | ||||
|  */ | ||||
| char *curl_easy_unescape(CURL *handle, const char *string, int length, | ||||
|                          int *olen) | ||||
| { | ||||
|   char *str = NULL; | ||||
|   size_t inputlen = length; | ||||
|   size_t outputlen; | ||||
|   CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen, | ||||
|                                 FALSE); | ||||
|   if(res) | ||||
|     return NULL; | ||||
|   if(olen) | ||||
|     *olen = curlx_uztosi(outputlen); | ||||
|   return str; | ||||
| } | ||||
|  | ||||
| /* For operating systems/environments that use different malloc/free | ||||
|   | ||||
							
								
								
									
										10
									
								
								lib/escape.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								lib/escape.h
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| #ifndef __ESCAPE_H | ||||
| #define __ESCAPE_H | ||||
| #ifndef HEADER_CURL_ESCAPE_H | ||||
| #define HEADER_CURL_ESCAPE_H | ||||
|  | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
| @@ -8,7 +8,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -25,5 +25,9 @@ | ||||
| /* Escape and unescape URL encoding in strings. The functions return a new | ||||
|  * allocated string or NULL if an error occurred.  */ | ||||
|  | ||||
| CURLcode Curl_urldecode(struct SessionHandle *data, | ||||
|                         const char *string, size_t length, | ||||
|                         char **ostring, size_t *olen, | ||||
|                         bool reject_crlf); | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										50
									
								
								lib/file.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								lib/file.c
									
									
									
									
									
								
							| @@ -67,6 +67,7 @@ | ||||
| #include "url.h" | ||||
| #include "curl_memory.h" | ||||
| #include "parsedate.h" /* for the week day and month names */ | ||||
| #include "warnless.h" | ||||
|  | ||||
| #define _MPRINTF_REPLACE /* use our functions only */ | ||||
| #include <curl/mprintf.h> | ||||
| @@ -93,6 +94,9 @@ static CURLcode file_do(struct connectdata *, bool *done); | ||||
| static CURLcode file_done(struct connectdata *conn, | ||||
|                           CURLcode status, bool premature); | ||||
| static CURLcode file_connect(struct connectdata *conn, bool *done); | ||||
| static CURLcode file_disconnect(struct connectdata *conn, | ||||
|                                 bool dead_connection); | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * FILE scheme handler. | ||||
| @@ -109,12 +113,13 @@ const struct Curl_handler Curl_handler_file = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   file_disconnect,                      /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
|   0,                                    /* defport */ | ||||
|   CURLPROTO_FILE,                       /* protocol */ | ||||
|   PROTOPT_NONETWORK                     /* flags */ | ||||
|   PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -179,7 +184,7 @@ static CURLcode file_range(struct connectdata *conn) | ||||
| static CURLcode file_connect(struct connectdata *conn, bool *done) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   char *real_path = curl_easy_unescape(data, data->state.path, 0, NULL); | ||||
|   char *real_path; | ||||
|   struct FILEPROTO *file; | ||||
|   int fd; | ||||
| #ifdef DOS_FILESYSTEM | ||||
| @@ -187,13 +192,14 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) | ||||
|   char *actual_path; | ||||
| #endif | ||||
|  | ||||
|   if(!real_path) | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
|   /* If there already is a protocol-specific struct allocated for this | ||||
|      sessionhandle, deal with it */ | ||||
|   Curl_reset_reqproto(conn); | ||||
|  | ||||
|   real_path = curl_easy_unescape(data, data->state.path, 0, NULL); | ||||
|   if(!real_path) | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
|   if(!data->state.proto.file) { | ||||
|     file = calloc(1, sizeof(struct FILEPROTO)); | ||||
|     if(!file) { | ||||
| @@ -206,10 +212,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) | ||||
|     /* file is not a protocol that can deal with "persistancy" */ | ||||
|     file = data->state.proto.file; | ||||
|     Curl_safefree(file->freepath); | ||||
|     file->path = NULL; | ||||
|     if(file->fd != -1) | ||||
|       close(file->fd); | ||||
|     file->path = NULL; | ||||
|     file->freepath = NULL; | ||||
|     file->fd = -1; | ||||
|   } | ||||
|  | ||||
| @@ -266,10 +271,31 @@ static CURLcode file_done(struct connectdata *conn, | ||||
|   struct FILEPROTO *file = conn->data->state.proto.file; | ||||
|   (void)status; /* not used */ | ||||
|   (void)premature; /* not used */ | ||||
|   Curl_safefree(file->freepath); | ||||
|  | ||||
|   if(file) { | ||||
|     Curl_safefree(file->freepath); | ||||
|     file->path = NULL; | ||||
|     if(file->fd != -1) | ||||
|       close(file->fd); | ||||
|     file->fd = -1; | ||||
|   } | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| static CURLcode file_disconnect(struct connectdata *conn, | ||||
|                                 bool dead_connection) | ||||
| { | ||||
|   struct FILEPROTO *file = conn->data->state.proto.file; | ||||
|   (void)dead_connection; /* not used */ | ||||
|  | ||||
|   if(file) { | ||||
|     Curl_safefree(file->freepath); | ||||
|     file->path = NULL; | ||||
|     if(file->fd != -1) | ||||
|       close(file->fd); | ||||
|     file->fd = -1; | ||||
|   } | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
| @@ -422,7 +448,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done) | ||||
|   curl_off_t expected_size=0; | ||||
|   bool fstated=FALSE; | ||||
|   ssize_t nread; | ||||
|   size_t bytestoread; | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   char *buf = data->state.buffer; | ||||
|   curl_off_t bytecount = 0; | ||||
| @@ -544,7 +569,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done) | ||||
|  | ||||
|   while(res == CURLE_OK) { | ||||
|     /* Don't fill a whole buffer if we want less than all data */ | ||||
|     bytestoread = (expected_size < BUFSIZE-1)?(size_t)expected_size:BUFSIZE-1; | ||||
|     size_t bytestoread = | ||||
|       (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ? | ||||
|       curlx_sotouz(expected_size) : BUFSIZE - 1; | ||||
|  | ||||
|     nread = read(fd, buf, bytestoread); | ||||
|  | ||||
|     if(nread > 0) | ||||
|   | ||||
| @@ -48,8 +48,7 @@ void Curl_fileinfo_dtor(void *user, void *element) | ||||
|   if(!finfo) | ||||
|     return; | ||||
|  | ||||
|   if(finfo->b_data) | ||||
|     free(finfo->b_data); | ||||
|   Curl_safefree(finfo->b_data); | ||||
|  | ||||
|   free(finfo); | ||||
| } | ||||
|   | ||||
							
								
								
									
										177
									
								
								lib/formdata.c
									
									
									
									
									
								
							
							
						
						
									
										177
									
								
								lib/formdata.c
									
									
									
									
									
								
							| @@ -156,8 +156,6 @@ static FormInfo * AddFormInfo(char *value, | ||||
|     /* then move the original 'more' to point to ourselves */ | ||||
|     parent_form_info->more = form_info; | ||||
|   } | ||||
|   else | ||||
|     return NULL; | ||||
|  | ||||
|   return form_info; | ||||
| } | ||||
| @@ -458,9 +456,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, | ||||
|         if(current_form->value) { | ||||
|           if(current_form->flags & HTTPPOST_FILENAME) { | ||||
|             if(filename) { | ||||
|               if((current_form = AddFormInfo(strdup(filename), | ||||
|                                              NULL, current_form)) == NULL) | ||||
|               char *fname = strdup(filename); | ||||
|               if(!fname) | ||||
|                 return_value = CURL_FORMADD_MEMORY; | ||||
|               else { | ||||
|                 form = AddFormInfo(fname, NULL, current_form); | ||||
|                 if(!form) { | ||||
|                   Curl_safefree(fname); | ||||
|                   return_value = CURL_FORMADD_MEMORY; | ||||
|                 } | ||||
|                 else { | ||||
|                   form->value_alloc = TRUE; | ||||
|                   current_form = form; | ||||
|                   form = NULL; | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|             else | ||||
|               return_value = CURL_FORMADD_NULL; | ||||
| @@ -535,10 +545,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, | ||||
|         if(current_form->contenttype) { | ||||
|           if(current_form->flags & HTTPPOST_FILENAME) { | ||||
|             if(contenttype) { | ||||
|               if((current_form = AddFormInfo(NULL, | ||||
|                                              strdup(contenttype), | ||||
|                                              current_form)) == NULL) | ||||
|               char *type = strdup(contenttype); | ||||
|               if(!type) | ||||
|                 return_value = CURL_FORMADD_MEMORY; | ||||
|               else { | ||||
|                 form = AddFormInfo(NULL, type, current_form); | ||||
|                 if(!form) { | ||||
|                   Curl_safefree(type); | ||||
|                   return_value = CURL_FORMADD_MEMORY; | ||||
|                 } | ||||
|                 else { | ||||
|                   form->contenttype_alloc = TRUE; | ||||
|                   current_form = form; | ||||
|                   form = NULL; | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|             else | ||||
|               return_value = CURL_FORMADD_NULL; | ||||
| @@ -596,6 +617,30 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if(CURL_FORMADD_OK != return_value) { | ||||
|     /* On error, free allocated fields for all nodes of the FormInfo linked | ||||
|        list without deallocating nodes. List nodes are deallocated later on */ | ||||
|     FormInfo *ptr; | ||||
|     for(ptr = first_form; ptr != NULL; ptr = ptr->more) { | ||||
|       if(ptr->name_alloc) { | ||||
|         Curl_safefree(ptr->name); | ||||
|         ptr->name_alloc = FALSE; | ||||
|       } | ||||
|       if(ptr->value_alloc) { | ||||
|         Curl_safefree(ptr->value); | ||||
|         ptr->value_alloc = FALSE; | ||||
|       } | ||||
|       if(ptr->contenttype_alloc) { | ||||
|         Curl_safefree(ptr->contenttype); | ||||
|         ptr->contenttype_alloc = FALSE; | ||||
|       } | ||||
|       if(ptr->showfilename_alloc) { | ||||
|         Curl_safefree(ptr->showfilename); | ||||
|         ptr->showfilename_alloc = FALSE; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if(CURL_FORMADD_OK == return_value) { | ||||
|     /* go through the list, check for completeness and if everything is | ||||
|      * alright add the HttpPost item otherwise set return_value accordingly */ | ||||
| @@ -675,32 +720,39 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, | ||||
|           prevtype = form->contenttype; | ||||
|       } | ||||
|     } | ||||
|     if(CURL_FORMADD_OK != return_value) { | ||||
|       /* On error, free allocated fields for nodes of the FormInfo linked | ||||
|          list which are not already owned by the httppost linked list | ||||
|          without deallocating nodes. List nodes are deallocated later on */ | ||||
|       FormInfo *ptr; | ||||
|       for(ptr = form; ptr != NULL; ptr = ptr->more) { | ||||
|         if(ptr->name_alloc) { | ||||
|           Curl_safefree(ptr->name); | ||||
|           ptr->name_alloc = FALSE; | ||||
|         } | ||||
|         if(ptr->value_alloc) { | ||||
|           Curl_safefree(ptr->value); | ||||
|           ptr->value_alloc = FALSE; | ||||
|         } | ||||
|         if(ptr->contenttype_alloc) { | ||||
|           Curl_safefree(ptr->contenttype); | ||||
|           ptr->contenttype_alloc = FALSE; | ||||
|         } | ||||
|         if(ptr->showfilename_alloc) { | ||||
|           Curl_safefree(ptr->showfilename); | ||||
|           ptr->showfilename_alloc = FALSE; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|   if(return_value) { | ||||
|     /* we return on error, free possibly allocated fields */ | ||||
|     if(!form) | ||||
|       form = current_form; | ||||
|     if(form) { | ||||
|       if(form->name_alloc) | ||||
|         free(form->name); | ||||
|       if(form->value_alloc) | ||||
|         free(form->value); | ||||
|       if(form->contenttype_alloc) | ||||
|         free(form->contenttype); | ||||
|       if(form->showfilename_alloc) | ||||
|         free(form->showfilename); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* always delete the allocated memory before returning */ | ||||
|   form = first_form; | ||||
|   while(form != NULL) { | ||||
|     FormInfo *delete_form; | ||||
|  | ||||
|     delete_form = form; | ||||
|     form = form->more; | ||||
|     free (delete_form); | ||||
|   /* Always deallocate FormInfo linked list nodes without touching node | ||||
|      fields given that these have either been deallocated or are owned | ||||
|      now by the httppost linked list */ | ||||
|   while(first_form) { | ||||
|     FormInfo *ptr = first_form->more; | ||||
|     Curl_safefree(first_form); | ||||
|     first_form = ptr; | ||||
|   } | ||||
|  | ||||
|   return return_value; | ||||
| @@ -855,10 +907,11 @@ int curl_formget(struct curl_httppost *form, void *arg, | ||||
|  | ||||
|       do { | ||||
|         nread = readfromfile(&temp, buffer, sizeof(buffer)); | ||||
|         if((nread == (size_t) -1) || (nread != append(arg, buffer, nread))) { | ||||
|           if(temp.fp) { | ||||
|         if((nread == (size_t) -1) || | ||||
|            (nread > sizeof(buffer)) || | ||||
|            (nread != append(arg, buffer, nread))) { | ||||
|           if(temp.fp) | ||||
|             fclose(temp.fp); | ||||
|           } | ||||
|           Curl_formclean(&data); | ||||
|           return -1; | ||||
|         } | ||||
| @@ -1017,7 +1070,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|                         boundary); | ||||
|  | ||||
|   if(result) { | ||||
|     free(boundary); | ||||
|     Curl_safefree(boundary); | ||||
|     return result; | ||||
|   } | ||||
|   /* we DO NOT include that line in the total size of the POST, since it'll be | ||||
| @@ -1060,7 +1113,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|       /* If used, this is a link to more file names, we must then do | ||||
|          the magic to include several files with the same field name */ | ||||
|  | ||||
|       Curl_safefree(fileboundary); | ||||
|       fileboundary = Curl_FormBoundary(); | ||||
|       if(!fileboundary) { | ||||
|         result = CURLE_OUT_OF_MEMORY; | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       result = AddFormDataf(&form, &size, | ||||
|                             "\r\nContent-Type: multipart/mixed," | ||||
| @@ -1084,9 +1142,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|         if(!file->showfilename) { | ||||
|           filebasename = strippath(file->contents); | ||||
|           if(!filebasename) { | ||||
|             Curl_formclean(&firstform); | ||||
|             free(boundary); | ||||
|             return CURLE_OUT_OF_MEMORY; | ||||
|             result = CURLE_OUT_OF_MEMORY; | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|  | ||||
| @@ -1096,8 +1153,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|                               fileboundary, | ||||
|                               (file->showfilename?file->showfilename: | ||||
|                                filebasename)); | ||||
|         if(filebasename) | ||||
|           free(filebasename); | ||||
|         Curl_safefree(filebasename); | ||||
|         if(result) | ||||
|           break; | ||||
|       } | ||||
| @@ -1114,8 +1170,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|                                 "; filename=\"%s\"", | ||||
|                                 (post->showfilename?post->showfilename: | ||||
|                                  filebasename)); | ||||
|           if(filebasename) | ||||
|             free(filebasename); | ||||
|           Curl_safefree(filebasename); | ||||
|         } | ||||
|  | ||||
|         if(result) | ||||
| @@ -1139,11 +1194,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|           break; | ||||
|         curList = curList->next; | ||||
|       } | ||||
|       if(result) { | ||||
|         Curl_formclean(&firstform); | ||||
|         free(boundary); | ||||
|         return result; | ||||
|       } | ||||
|       if(result) | ||||
|         break; | ||||
|  | ||||
|       result = AddFormDataf(&form, &size, "\r\n\r\n"); | ||||
|       if(result) | ||||
| @@ -1165,7 +1217,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|  | ||||
|         if(fileread) { | ||||
|           if(fileread != stdin) { | ||||
|             /* close the file again */ | ||||
|             /* close the file */ | ||||
|             fclose(fileread); | ||||
|             /* add the file name only - for later reading from this */ | ||||
|             result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); | ||||
| @@ -1209,11 +1261,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|       file = file->more; | ||||
|     } while(file && !result); /* for each specified file for this field */ | ||||
|  | ||||
|     if(result) { | ||||
|       Curl_formclean(&firstform); | ||||
|       free(boundary); | ||||
|       return result; | ||||
|     } | ||||
|     if(result) | ||||
|       break; | ||||
|  | ||||
|     if(post->more) { | ||||
|       /* this was a multiple-file inclusion, make a termination file | ||||
| @@ -1221,31 +1270,29 @@ CURLcode Curl_getformdata(struct SessionHandle *data, | ||||
|       result = AddFormDataf(&form, &size, | ||||
|                            "\r\n--%s--", | ||||
|                            fileboundary); | ||||
|       free(fileboundary); | ||||
|       if(result) | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|   } while((post = post->next) != NULL); /* for each field */ | ||||
|   if(result) { | ||||
|     Curl_formclean(&firstform); | ||||
|     free(boundary); | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   /* end-boundary for everything */ | ||||
|   if(CURLE_OK == result) | ||||
|     result = AddFormDataf(&form, &size, | ||||
|                           "\r\n--%s--\r\n", | ||||
|                           boundary); | ||||
|  | ||||
|   if(result) { | ||||
|     Curl_formclean(&firstform); | ||||
|     free(boundary); | ||||
|     Curl_safefree(fileboundary); | ||||
|     Curl_safefree(boundary); | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   *sizep = size; | ||||
|  | ||||
|   free(boundary); | ||||
|   Curl_safefree(fileboundary); | ||||
|   Curl_safefree(boundary); | ||||
|  | ||||
|   *finalform = firstform; | ||||
|  | ||||
| @@ -1269,6 +1316,13 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * readfromfile() | ||||
|  * | ||||
|  * The read callback that this function may use can return a value larger than | ||||
|  * 'size' (which then this function returns) that indicates a problem and it | ||||
|  * must be properly dealt with | ||||
|  */ | ||||
| static size_t readfromfile(struct Form *form, char *buffer, | ||||
|                            size_t size) | ||||
| { | ||||
| @@ -1280,11 +1334,6 @@ static size_t readfromfile(struct Form *form, char *buffer, | ||||
|       return 0; | ||||
|     else | ||||
|       nread = form->fread_func(buffer, 1, size, form->data->line); | ||||
|  | ||||
|     if(nread > size) | ||||
|       /* the read callback can return a value larger than the buffer but | ||||
|          treat any such as no data in this case */ | ||||
|       nread = 0; | ||||
|   } | ||||
|   else { | ||||
|     if(!form->fp) { | ||||
|   | ||||
							
								
								
									
										546
									
								
								lib/ftp.c
									
									
									
									
									
								
							
							
						
						
									
										546
									
								
								lib/ftp.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -108,6 +108,8 @@ | ||||
| #endif | ||||
|  | ||||
| /* Local API functions */ | ||||
| static void state(struct connectdata *conn, | ||||
|                   ftpstate newstate); | ||||
| static CURLcode ftp_sendquote(struct connectdata *conn, | ||||
|                               struct curl_slist *quote); | ||||
| static CURLcode ftp_quit(struct connectdata *conn); | ||||
| @@ -132,10 +134,11 @@ static CURLcode ftp_done(struct connectdata *conn, | ||||
|                          CURLcode, bool premature); | ||||
| static CURLcode ftp_connect(struct connectdata *conn, bool *done); | ||||
| static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection); | ||||
| static CURLcode ftp_nextconnect(struct connectdata *conn); | ||||
| static CURLcode ftp_do_more(struct connectdata *conn, bool *completed); | ||||
| static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done); | ||||
| static int ftp_getsock(struct connectdata *conn, | ||||
|                        curl_socket_t *socks, | ||||
| static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks, | ||||
|                        int numsocks); | ||||
| static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, | ||||
|                               int numsocks); | ||||
| static CURLcode ftp_doing(struct connectdata *conn, | ||||
|                           bool *dophase_done); | ||||
| @@ -149,6 +152,11 @@ static void wc_data_dtor(void *ptr); | ||||
| static CURLcode ftp_state_post_retr_size(struct connectdata *conn, | ||||
|                                          curl_off_t filesize); | ||||
|  | ||||
| static CURLcode ftp_readresp(curl_socket_t sockfd, | ||||
|                              struct pingpong *pp, | ||||
|                              int *ftpcode, | ||||
|                              size_t *size); | ||||
|  | ||||
| /* easy-to-use macro: */ | ||||
| #define FTPSENDF(x,y,z)    if((result = Curl_ftpsendf(x,y,z)) != CURLE_OK) \ | ||||
|                               return result | ||||
| @@ -165,18 +173,20 @@ const struct Curl_handler Curl_handler_ftp = { | ||||
|   ftp_setup_connection,            /* setup_connection */ | ||||
|   ftp_do,                          /* do_it */ | ||||
|   ftp_done,                        /* done */ | ||||
|   ftp_nextconnect,                 /* do_more */ | ||||
|   ftp_do_more,                     /* do_more */ | ||||
|   ftp_connect,                     /* connect_it */ | ||||
|   ftp_multi_statemach,             /* connecting */ | ||||
|   ftp_doing,                       /* doing */ | ||||
|   ftp_getsock,                     /* proto_getsock */ | ||||
|   ftp_getsock,                     /* doing_getsock */ | ||||
|   ftp_domore_getsock,              /* domore_getsock */ | ||||
|   ZERO_NULL,                       /* perform_getsock */ | ||||
|   ftp_disconnect,                  /* disconnect */ | ||||
|   ZERO_NULL,                       /* readwrite */ | ||||
|   PORT_FTP,                        /* defport */ | ||||
|   CURLPROTO_FTP,                   /* protocol */ | ||||
|   PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */ | ||||
|   PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | ||||
|   | PROTOPT_NOURLQUERY /* flags */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -190,19 +200,20 @@ const struct Curl_handler Curl_handler_ftps = { | ||||
|   ftp_setup_connection,            /* setup_connection */ | ||||
|   ftp_do,                          /* do_it */ | ||||
|   ftp_done,                        /* done */ | ||||
|   ftp_nextconnect,                 /* do_more */ | ||||
|   ftp_do_more,                     /* do_more */ | ||||
|   ftp_connect,                     /* connect_it */ | ||||
|   ftp_multi_statemach,             /* connecting */ | ||||
|   ftp_doing,                       /* doing */ | ||||
|   ftp_getsock,                     /* proto_getsock */ | ||||
|   ftp_getsock,                     /* doing_getsock */ | ||||
|   ftp_domore_getsock,              /* domore_getsock */ | ||||
|   ZERO_NULL,                       /* perform_getsock */ | ||||
|   ftp_disconnect,                  /* disconnect */ | ||||
|   ZERO_NULL,                       /* readwrite */ | ||||
|   PORT_FTPS,                       /* defport */ | ||||
|   CURLPROTO_FTP | CURLPROTO_FTPS,  /* protocol */ | ||||
|   PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | | ||||
|   PROTOPT_NEEDSPWD /* flags */ | ||||
|   PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */ | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| @@ -222,6 +233,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -247,6 +259,7 @@ static const struct Curl_handler Curl_handler_ftps_proxy = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -304,19 +317,16 @@ static bool isBadFtpString(const char *string) | ||||
|  | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  * AllowServerConnect() | ||||
|  * AcceptServerConnect() | ||||
|  * | ||||
|  * When we've issue the PORT command, we have told the server to connect | ||||
|  * to us. This function will sit and wait here until the server has | ||||
|  * connected. | ||||
|  * After connection request is received from the server this function is | ||||
|  * called to accept the connection and close the listening socket | ||||
|  * | ||||
|  */ | ||||
| static CURLcode AllowServerConnect(struct connectdata *conn) | ||||
| static CURLcode AcceptServerConnect(struct connectdata *conn) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   curl_socket_t sock = conn->sock[SECONDARYSOCKET]; | ||||
|   long timeout_ms; | ||||
|   long interval_ms; | ||||
|   curl_socket_t s = CURL_SOCKET_BAD; | ||||
| #ifdef ENABLE_IPV6 | ||||
|   struct Curl_sockaddr_storage add; | ||||
| @@ -325,28 +335,6 @@ static CURLcode AllowServerConnect(struct connectdata *conn) | ||||
| #endif | ||||
|   curl_socklen_t size = (curl_socklen_t) sizeof(add); | ||||
|  | ||||
|   for(;;) { | ||||
|     timeout_ms = Curl_timeleft(data, NULL, TRUE); | ||||
|  | ||||
|     if(timeout_ms < 0) { | ||||
|       /* if a timeout was already reached, bail out */ | ||||
|       failf(data, "Timeout while waiting for server connect"); | ||||
|       return CURLE_OPERATION_TIMEDOUT; | ||||
|     } | ||||
|  | ||||
|     interval_ms = 1000;  /* use 1 second timeout intervals */ | ||||
|     if(timeout_ms < interval_ms) | ||||
|       interval_ms = timeout_ms; | ||||
|  | ||||
|     switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, interval_ms)) { | ||||
|     case -1: /* error */ | ||||
|       /* let's die here */ | ||||
|       failf(data, "Error while waiting for server connect"); | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|     case 0:  /* timeout */ | ||||
|       break; /* loop */ | ||||
|     default: | ||||
|       /* we have received data here */ | ||||
|   if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) { | ||||
|     size = sizeof(add); | ||||
|  | ||||
| @@ -362,10 +350,243 @@ static CURLcode AllowServerConnect(struct connectdata *conn) | ||||
|  | ||||
|   conn->sock[SECONDARYSOCKET] = s; | ||||
|   curlx_nonblock(s, TRUE); /* enable non-blocking */ | ||||
|   conn->sock_accepted[SECONDARYSOCKET] = TRUE; | ||||
|   return CURLE_OK; | ||||
|     } /* switch() */ | ||||
|  | ||||
| } | ||||
|   /* never reaches this point */ | ||||
|  | ||||
| /* | ||||
|  * ftp_timeleft_accept() returns the amount of milliseconds left allowed for | ||||
|  * waiting server to connect. If the value is negative, the timeout time has | ||||
|  * already elapsed. | ||||
|  * | ||||
|  * The start time is stored in progress.t_acceptdata - as set with | ||||
|  * Curl_pgrsTime(..., TIMER_STARTACCEPT); | ||||
|  * | ||||
|  */ | ||||
| static long ftp_timeleft_accept(struct SessionHandle *data) | ||||
| { | ||||
|   long timeout_ms = DEFAULT_ACCEPT_TIMEOUT; | ||||
|   long other; | ||||
|   struct timeval now; | ||||
|  | ||||
|   if(data->set.accepttimeout > 0) | ||||
|     timeout_ms = data->set.accepttimeout; | ||||
|  | ||||
|   now = Curl_tvnow(); | ||||
|  | ||||
|   /* check if the generic timeout possibly is set shorter */ | ||||
|   other =  Curl_timeleft(data, &now, FALSE); | ||||
|   if(other && (other < timeout_ms)) | ||||
|     /* note that this also works fine for when other happens to be negative | ||||
|        due to it already having elapsed */ | ||||
|     timeout_ms = other; | ||||
|   else { | ||||
|     /* subtract elapsed time */ | ||||
|     timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata); | ||||
|     if(!timeout_ms) | ||||
|       /* avoid returning 0 as that means no timeout! */ | ||||
|       return -1; | ||||
|   } | ||||
|  | ||||
|   return timeout_ms; | ||||
| } | ||||
|  | ||||
|  | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  * ReceivedServerConnect() | ||||
|  * | ||||
|  * After allowing server to connect to us from data port, this function | ||||
|  * checks both data connection for connection establishment and ctrl | ||||
|  * connection for a negative response regarding a failure in connecting | ||||
|  * | ||||
|  */ | ||||
| static CURLcode ReceivedServerConnect(struct connectdata* conn, bool* received) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET]; | ||||
|   curl_socket_t data_sock = conn->sock[SECONDARYSOCKET]; | ||||
|   struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|   struct pingpong *pp = &ftpc->pp; | ||||
|   int result; | ||||
|   long timeout_ms; | ||||
|   ssize_t nread; | ||||
|   int ftpcode; | ||||
|  | ||||
|   *received = FALSE; | ||||
|  | ||||
|   timeout_ms = ftp_timeleft_accept(data); | ||||
|   infof(data, "Checking for server connect\n"); | ||||
|   if(timeout_ms < 0) { | ||||
|     /* if a timeout was already reached, bail out */ | ||||
|     failf(data, "Accept timeout occurred while waiting server connect"); | ||||
|     return CURLE_FTP_ACCEPT_TIMEOUT; | ||||
|   } | ||||
|  | ||||
|   /* First check whether there is a cached response from server */ | ||||
|   if(pp->cache_size && pp->cache && pp->cache[0] > '3') { | ||||
|     /* Data connection could not be established, let's return */ | ||||
|     infof(data, "There is negative response in cache while serv connect\n"); | ||||
|     Curl_GetFTPResponse(&nread, conn, &ftpcode); | ||||
|     return CURLE_FTP_ACCEPT_FAILED; | ||||
|   } | ||||
|  | ||||
|   result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0); | ||||
|  | ||||
|   /* see if the connection request is already here */ | ||||
|   switch (result) { | ||||
|   case -1: /* error */ | ||||
|     /* let's die here */ | ||||
|     failf(data, "Error while waiting for server connect"); | ||||
|     return CURLE_FTP_ACCEPT_FAILED; | ||||
|   case 0:  /* Server connect is not received yet */ | ||||
|     break; /* loop */ | ||||
|   default: | ||||
|  | ||||
|     if(result & CURL_CSELECT_IN2) { | ||||
|       infof(data, "Ready to accept data connection from server\n"); | ||||
|       *received = TRUE; | ||||
|     } | ||||
|     else if(result & CURL_CSELECT_IN) { | ||||
|       infof(data, "Ctrl conn has data while waiting for data conn\n"); | ||||
|       Curl_GetFTPResponse(&nread, conn, &ftpcode); | ||||
|  | ||||
|       if(ftpcode/100 > 3) | ||||
|         return CURLE_FTP_ACCEPT_FAILED; | ||||
|  | ||||
|       return CURLE_FTP_WEIRD_SERVER_REPLY; | ||||
|     } | ||||
|  | ||||
|     break; | ||||
|   } /* switch() */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
|  | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  * InitiateTransfer() | ||||
|  * | ||||
|  * After connection from server is accepted this function is called to | ||||
|  * setup transfer parameters and initiate the data transfer. | ||||
|  * | ||||
|  */ | ||||
| static CURLcode InitiateTransfer(struct connectdata *conn) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   struct FTP *ftp = data->state.proto.ftp; | ||||
|   CURLcode result = CURLE_OK; | ||||
|  | ||||
|   if(conn->ssl[SECONDARYSOCKET].use) { | ||||
|     /* since we only have a plaintext TCP connection here, we must now | ||||
|      * do the TLS stuff */ | ||||
|     infof(data, "Doing the SSL/TLS handshake on the data stream\n"); | ||||
|     result = Curl_ssl_connect(conn, SECONDARYSOCKET); | ||||
|     if(result) | ||||
|       return result; | ||||
|   } | ||||
|  | ||||
|   if(conn->proto.ftpc.state_saved == FTP_STOR) { | ||||
|     *(ftp->bytecountp)=0; | ||||
|  | ||||
|     /* When we know we're uploading a specified file, we can get the file | ||||
|        size prior to the actual upload. */ | ||||
|  | ||||
|     Curl_pgrsSetUploadSize(data, data->set.infilesize); | ||||
|  | ||||
|     /* set the SO_SNDBUF for the secondary socket for those who need it */ | ||||
|     Curl_sndbufset(conn->sock[SECONDARYSOCKET]); | ||||
|  | ||||
|     Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ | ||||
|                         SECONDARYSOCKET, ftp->bytecountp); | ||||
|   } | ||||
|   else { | ||||
|     /* FTP download: */ | ||||
|     Curl_setup_transfer(conn, SECONDARYSOCKET, | ||||
|         conn->proto.ftpc.retr_size_saved, FALSE, | ||||
|         ftp->bytecountp, -1, NULL); /* no upload here */ | ||||
|   } | ||||
|  | ||||
|   conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ | ||||
|   state(conn, FTP_STOP); | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  * AllowServerConnect() | ||||
|  * | ||||
|  * When we've issue the PORT command, we have told the server to connect | ||||
|  * to us. This function | ||||
|  *   - will sit and wait here until the server has connected for easy interface | ||||
|  *   - will check whether data connection is established if so it is accepted | ||||
|  *   for multi interface | ||||
|  * | ||||
|  */ | ||||
| static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected) | ||||
| { | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   long timeout_ms; | ||||
|   long interval_ms; | ||||
|   CURLcode ret = CURLE_OK; | ||||
|  | ||||
|   *connected = FALSE; | ||||
|   infof(data, "Preparing for accepting server on data port\n"); | ||||
|  | ||||
|   /* Save the time we start accepting server connect */ | ||||
|   Curl_pgrsTime(data, TIMER_STARTACCEPT); | ||||
|  | ||||
|   for(;;) { | ||||
|     timeout_ms = ftp_timeleft_accept(data); | ||||
|     if(timeout_ms < 0) { | ||||
|       /* if a timeout was already reached, bail out */ | ||||
|       failf(data, "Accept timeout occurred while waiting server connect"); | ||||
|       return CURLE_FTP_ACCEPT_TIMEOUT; | ||||
|     } | ||||
|  | ||||
|     /* see if the connection request is already here */ | ||||
|     ret = ReceivedServerConnect(conn, connected); | ||||
|     if(ret) | ||||
|       return ret; | ||||
|  | ||||
|     if(*connected) { | ||||
|       ret = AcceptServerConnect(conn); | ||||
|       if(ret) | ||||
|         return ret; | ||||
|  | ||||
|       ret = InitiateTransfer(conn); | ||||
|       if(ret) | ||||
|         return ret; | ||||
|  | ||||
|       break; /* connection is accepted, break the loop */ | ||||
|     } | ||||
|     else { | ||||
|       if(data->state.used_interface == Curl_if_easy) { | ||||
|         interval_ms = 1000; | ||||
|         if(timeout_ms < interval_ms) | ||||
|           interval_ms = timeout_ms; | ||||
|  | ||||
|         /* sleep for 1 second and then continue */ | ||||
|         Curl_socket_ready(CURL_SOCKET_BAD, CURL_SOCKET_BAD, interval_ms); | ||||
|       } | ||||
|       else { | ||||
|         /* Add timeout to multi handle and break out of the loop */ | ||||
|         if(ret == CURLE_OK && *connected == FALSE) { | ||||
|           if(data->set.accepttimeout > 0) | ||||
|             Curl_expire(data, data->set.accepttimeout); | ||||
|           else | ||||
|             Curl_expire(data, DEFAULT_ACCEPT_TIMEOUT); | ||||
|         } | ||||
|  | ||||
|         break; /* connection was not accepted immediately */ | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| /* macro to check for a three-digit ftp status code at the start of the | ||||
| @@ -634,6 +855,41 @@ static int ftp_getsock(struct connectdata *conn, | ||||
|   return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); | ||||
| } | ||||
|  | ||||
| /* For the FTP "DO_MORE" phase only */ | ||||
| static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, | ||||
|                               int numsocks) | ||||
| { | ||||
|   struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|  | ||||
|   if(!numsocks) | ||||
|     return GETSOCK_BLANK; | ||||
|  | ||||
|   /* When in DO_MORE state, we could be either waiting for us to connect to a | ||||
|      remote site, or we could wait for that site to connect to us. Or just | ||||
|      handle ordinary commands. | ||||
|  | ||||
|      When waiting for a connect, we will be in FTP_STOP state and then we wait | ||||
|      for the secondary socket to become writeable. If we're in another state, | ||||
|      we're still handling commands on the control (primary) connection. | ||||
|  | ||||
|   */ | ||||
|  | ||||
|   switch(ftpc->state) { | ||||
|   case FTP_STOP: | ||||
|     break; | ||||
|   default: | ||||
|     return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); | ||||
|   } | ||||
|  | ||||
|   socks[0] = conn->sock[SECONDARYSOCKET]; | ||||
|   if(ftpc->wait_data_conn) { | ||||
|     socks[1] = conn->sock[FIRSTSOCKET]; | ||||
|     return GETSOCK_READSOCK(0) | GETSOCK_READSOCK(1); | ||||
|   } | ||||
|  | ||||
|   return GETSOCK_READSOCK(0); | ||||
| } | ||||
|  | ||||
| /* This is called after the FTP_QUOTE state is passed. | ||||
|  | ||||
|    ftp_state_cwd() sends the range of CWD commands to the server to change to | ||||
| @@ -717,6 +973,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|   unsigned short port_min = 0; | ||||
|   unsigned short port_max = 0; | ||||
|   unsigned short port; | ||||
|   bool possibly_non_local = TRUE; | ||||
|  | ||||
|   char *addr = NULL; | ||||
|  | ||||
| @@ -819,8 +1076,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|     if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { | ||||
|       failf(data, "getsockname() failed: %s", | ||||
|           Curl_strerror(conn, SOCKERRNO) ); | ||||
|       if(addr) | ||||
|         free(addr); | ||||
|       Curl_safefree(addr); | ||||
|       return CURLE_FTP_PORT_FAILED; | ||||
|     } | ||||
|     switch(sa->sa_family) { | ||||
| @@ -834,6 +1090,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|       break; | ||||
|     } | ||||
|     host = hbuf; /* use this host name */ | ||||
|     possibly_non_local = FALSE; /* we know it is local now */ | ||||
|   } | ||||
|  | ||||
|   /* resolv ip/host to ip */ | ||||
| @@ -849,27 +1106,22 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|   else | ||||
|     res = NULL; /* failure! */ | ||||
|  | ||||
|   if(addr) | ||||
|     free(addr); | ||||
|  | ||||
|   if(res == NULL) { | ||||
|     failf(data, "Curl_resolv failed, we can not recover!"); | ||||
|     failf(data, "failed to resolve the address provided to PORT: %s", host); | ||||
|     Curl_safefree(addr); | ||||
|     return CURLE_FTP_PORT_FAILED; | ||||
|   } | ||||
|  | ||||
|   Curl_safefree(addr); | ||||
|   host = NULL; | ||||
|  | ||||
|   /* step 2, create a socket for the requested address */ | ||||
|  | ||||
|   portsock = CURL_SOCKET_BAD; | ||||
|   error = 0; | ||||
|   for(ai = res; ai; ai = ai->ai_next) { | ||||
|     /* | ||||
|      * Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype): | ||||
|      */ | ||||
|     if(ai->ai_socktype == 0) | ||||
|       ai->ai_socktype = conn->socktype; | ||||
|  | ||||
|     portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | ||||
|     if(portsock == CURL_SOCKET_BAD) { | ||||
|     result = Curl_socket(conn, ai, NULL, &portsock); | ||||
|     if(result) { | ||||
|       error = SOCKERRNO; | ||||
|       continue; | ||||
|     } | ||||
| @@ -896,12 +1148,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|     if(bind(portsock, sa, sslen) ) { | ||||
|       /* It failed. */ | ||||
|       error = SOCKERRNO; | ||||
|       if(error == EADDRNOTAVAIL) { | ||||
|  | ||||
|       if(possibly_non_local && (error == EADDRNOTAVAIL)) { | ||||
|         /* The requested bind address is not local.  Use the address used for | ||||
|          * the control connection instead and restart the port loop | ||||
|          */ | ||||
|         failf(data, "bind(port=%hu) failed: %s", port, | ||||
|  | ||||
|         infof(data, "bind(port=%hu) on non-local address failed: %s\n", port, | ||||
|               Curl_strerror(conn, error) ); | ||||
|  | ||||
|         sslen = sizeof(ss); | ||||
| @@ -912,6 +1164,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|           return CURLE_FTP_PORT_FAILED; | ||||
|         } | ||||
|         port = port_min; | ||||
|         possibly_non_local = FALSE; /* don't try this again */ | ||||
|         continue; | ||||
|       } | ||||
|       else if(error != EADDRINUSE && error != EACCES) { | ||||
| @@ -1001,6 +1254,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|                              sa->sa_family == AF_INET?1:2, | ||||
|                              myhost, port); | ||||
|       if(result) { | ||||
|         failf(data, "Failure sending EPRT command: %s", | ||||
|               curl_easy_strerror(result)); | ||||
|         Curl_closesocket(conn, portsock); | ||||
|         /* don't retry using PORT */ | ||||
|         ftpc->count1 = PORT; | ||||
| @@ -1028,6 +1283,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, | ||||
|  | ||||
|       result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp); | ||||
|       if(result) { | ||||
|         failf(data, "Failure sending PORT command: %s", | ||||
|               curl_easy_strerror(result)); | ||||
|         Curl_closesocket(conn, portsock); | ||||
|         /* bail out */ | ||||
|         state(conn, FTP_STOP); | ||||
| @@ -2114,11 +2371,10 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn, | ||||
| } | ||||
|  | ||||
| static CURLcode ftp_state_stor_resp(struct connectdata *conn, | ||||
|                                     int ftpcode) | ||||
|                                     int ftpcode, ftpstate instate) | ||||
| { | ||||
|   CURLcode result = CURLE_OK; | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   struct FTP *ftp = data->state.proto.ftp; | ||||
|  | ||||
|   if(ftpcode>=400) { | ||||
|     failf(data, "Failed FTP upload: %0d", ftpcode); | ||||
| @@ -2126,41 +2382,29 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn, | ||||
|     return CURLE_UPLOAD_FAILED; | ||||
|   } | ||||
|  | ||||
|   if(data->set.ftp_use_port) { | ||||
|     /* BLOCKING */ | ||||
|   conn->proto.ftpc.state_saved = instate; | ||||
|  | ||||
|   /* PORT means we are now awaiting the server to connect to us. */ | ||||
|     result = AllowServerConnect(conn); | ||||
|   if(data->set.ftp_use_port) { | ||||
|     bool connected; | ||||
|  | ||||
|     result = AllowServerConnect(conn, &connected); | ||||
|     if(result) | ||||
|       return result; | ||||
|   } | ||||
|  | ||||
|   if(conn->ssl[SECONDARYSOCKET].use) { | ||||
|     /* since we only have a plaintext TCP connection here, we must now | ||||
|        do the TLS stuff */ | ||||
|     infof(data, "Doing the SSL/TLS handshake on the data stream\n"); | ||||
|     /* BLOCKING */ | ||||
|     result = Curl_ssl_connect(conn, SECONDARYSOCKET); | ||||
|     if(result) | ||||
|       return result; | ||||
|   } | ||||
|  | ||||
|   *(ftp->bytecountp)=0; | ||||
|  | ||||
|   /* When we know we're uploading a specified file, we can get the file | ||||
|      size prior to the actual upload. */ | ||||
|  | ||||
|   Curl_pgrsSetUploadSize(data, data->set.infilesize); | ||||
|  | ||||
|   /* set the SO_SNDBUF for the secondary socket for those who need it */ | ||||
|   Curl_sndbufset(conn->sock[SECONDARYSOCKET]); | ||||
|  | ||||
|   Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ | ||||
|                       SECONDARYSOCKET, ftp->bytecountp); | ||||
|     if(!connected) { | ||||
|       struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|       infof(data, "Data conn was not available immediately\n"); | ||||
|       /* as there's not necessarily an immediate action on the control | ||||
|          connection now, we halt the state machine */ | ||||
|       state(conn, FTP_STOP); | ||||
|       ftpc->wait_data_conn = TRUE; | ||||
|     } | ||||
|  | ||||
|   conn->proto.ftpc.pp.pending_resp = TRUE; /* expect a server response */ | ||||
|  | ||||
|   return result; | ||||
|     return CURLE_OK; | ||||
|   } | ||||
|   else | ||||
|     return InitiateTransfer(conn); | ||||
| } | ||||
|  | ||||
| /* for LIST and RETR responses */ | ||||
| @@ -2241,22 +2485,6 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn, | ||||
|     else if(ftp->downloadsize > -1) | ||||
|       size = ftp->downloadsize; | ||||
|  | ||||
|     if(data->set.ftp_use_port) { | ||||
|       /* BLOCKING */ | ||||
|       result = AllowServerConnect(conn); | ||||
|       if(result) | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     if(conn->ssl[SECONDARYSOCKET].use) { | ||||
|       /* since we only have a plaintext TCP connection here, we must now | ||||
|          do the TLS stuff */ | ||||
|       infof(data, "Doing the SSL/TLS handshake on the data stream\n"); | ||||
|       result = Curl_ssl_connect(conn, SECONDARYSOCKET); | ||||
|       if(result) | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     if(size > data->req.maxdownload && data->req.maxdownload > 0) | ||||
|       size = data->req.size = data->req.maxdownload; | ||||
|     else if((instate != FTP_LIST) && (data->set.prefer_ascii)) | ||||
| @@ -2268,11 +2496,25 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn, | ||||
|       infof(data, "Getting file with size: %" FORMAT_OFF_T "\n", size); | ||||
|  | ||||
|     /* FTP download: */ | ||||
|     Curl_setup_transfer(conn, SECONDARYSOCKET, size, FALSE, | ||||
|                         ftp->bytecountp, -1, NULL); /* no upload here */ | ||||
|     conn->proto.ftpc.state_saved = instate; | ||||
|     conn->proto.ftpc.retr_size_saved = size; | ||||
|  | ||||
|     conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ | ||||
|     if(data->set.ftp_use_port) { | ||||
|       bool connected; | ||||
|  | ||||
|       result = AllowServerConnect(conn, &connected); | ||||
|       if(result) | ||||
|         return result; | ||||
|  | ||||
|       if(!connected) { | ||||
|         struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|         infof(data, "Data conn was not available immediately\n"); | ||||
|         state(conn, FTP_STOP); | ||||
|         ftpc->wait_data_conn = TRUE; | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|       return InitiateTransfer(conn); | ||||
|   } | ||||
|   else { | ||||
|     if((instate == FTP_LIST) && (ftpcode == 450)) { | ||||
| @@ -2420,7 +2662,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) | ||||
|   if(pp->sendleft) | ||||
|     return Curl_pp_flushsend(pp); | ||||
|  | ||||
|   /* we read a piece of response */ | ||||
|   result = ftp_readresp(sock, pp, &ftpcode, &nread); | ||||
|   if(result) | ||||
|     return result; | ||||
| @@ -2453,7 +2694,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) | ||||
|       } | ||||
| #endif | ||||
|  | ||||
|       if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) { | ||||
|       if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { | ||||
|         /* We don't have a SSL/TLS connection yet, but FTPS is | ||||
|            requested. Try a FTPS connection now */ | ||||
|  | ||||
| @@ -2509,7 +2750,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) | ||||
|         /* remain in this same state */ | ||||
|       } | ||||
|       else { | ||||
|         if(data->set.ftp_ssl > CURLUSESSL_TRY) | ||||
|         if(data->set.use_ssl > CURLUSESSL_TRY) | ||||
|           /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */ | ||||
|           result = CURLE_USE_SSL_FAILED; | ||||
|         else | ||||
| @@ -2532,7 +2773,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) | ||||
|  | ||||
|     case FTP_PBSZ: | ||||
|       PPSENDF(&ftpc->pp, "PROT %c", | ||||
|               data->set.ftp_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); | ||||
|               data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); | ||||
|       state(conn, FTP_PROT); | ||||
|  | ||||
|       break; | ||||
| @@ -2541,10 +2782,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) | ||||
|       if(ftpcode/100 == 2) | ||||
|         /* We have enabled SSL for the data connection! */ | ||||
|         conn->ssl[SECONDARYSOCKET].use = | ||||
|           (data->set.ftp_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE; | ||||
|           (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE; | ||||
|       /* FTP servers typically responds with 500 if they decide to reject | ||||
|          our 'P' request */ | ||||
|       else if(data->set.ftp_ssl > CURLUSESSL_CONTROL) | ||||
|       else if(data->set.use_ssl > CURLUSESSL_CONTROL) | ||||
|         /* we failed and bails out */ | ||||
|         return CURLE_USE_SSL_FAILED; | ||||
|  | ||||
| @@ -2826,7 +3067,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) | ||||
|       break; | ||||
|  | ||||
|     case FTP_STOR: | ||||
|       result = ftp_state_stor_resp(conn, ftpcode); | ||||
|       result = ftp_state_stor_resp(conn, ftpcode, ftpc->state); | ||||
|       break; | ||||
|  | ||||
|     case FTP_QUIT: | ||||
| @@ -3042,8 +3283,11 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, | ||||
|   case CURLE_BAD_DOWNLOAD_RESUME: | ||||
|   case CURLE_FTP_WEIRD_PASV_REPLY: | ||||
|   case CURLE_FTP_PORT_FAILED: | ||||
|   case CURLE_FTP_ACCEPT_FAILED: | ||||
|   case CURLE_FTP_ACCEPT_TIMEOUT: | ||||
|   case CURLE_FTP_COULDNT_SET_TYPE: | ||||
|   case CURLE_FTP_COULDNT_RETR_FILE: | ||||
|   case CURLE_PARTIAL_FILE: | ||||
|   case CURLE_UPLOAD_FAILED: | ||||
|   case CURLE_REMOTE_ACCESS_DENIED: | ||||
|   case CURLE_FILESIZE_EXCEEDED: | ||||
| @@ -3083,8 +3327,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, | ||||
|   path = curl_easy_unescape(data, path_to_use, 0, NULL); | ||||
|   if(!path) { | ||||
|     /* out of memory, but we can limp along anyway (and should try to | ||||
|      * since we're in the out of memory cleanup path) */ | ||||
|     ftpc->prevpath = NULL; /* no path */ | ||||
|      * since we may already be in the out of memory cleanup path) */ | ||||
|     if(!result) | ||||
|       result = CURLE_OUT_OF_MEMORY; | ||||
|     ftpc->ctl_valid = FALSE; /* mark control connection as bad */ | ||||
|     conn->bits.close = TRUE; /* mark for connection closure */ | ||||
|     ftpc->prevpath = NULL; /* no path remembering */ | ||||
|   } | ||||
|   else { | ||||
|     size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */ | ||||
| @@ -3122,6 +3370,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, | ||||
|     if(!result && ftpc->dont_check && data->req.maxdownload > 0) | ||||
|       /* partial download completed */ | ||||
|       result = Curl_pp_sendf(pp, "ABOR"); | ||||
|       if(result) { | ||||
|         failf(data, "Failure sending ABOR command: %s", | ||||
|               curl_easy_strerror(result)); | ||||
|         ftpc->ctl_valid = FALSE; /* mark control connection as bad */ | ||||
|         conn->bits.close = TRUE; /* mark for connection closure */ | ||||
|       } | ||||
|  | ||||
|     if(conn->ssl[SECONDARYSOCKET].use) { | ||||
|       /* The secondary socket is using SSL so we must close down that part | ||||
| @@ -3134,6 +3388,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, | ||||
|     if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) { | ||||
|       Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); | ||||
|       conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; | ||||
|       conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -3403,28 +3658,54 @@ static CURLcode ftp_range(struct connectdata *conn) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * ftp_nextconnect() | ||||
|  * ftp_do_more() | ||||
|  * | ||||
|  * This function shall be called when the second FTP (data) connection is | ||||
|  * connected. | ||||
|  */ | ||||
|  | ||||
| static CURLcode ftp_nextconnect(struct connectdata *conn) | ||||
| static CURLcode ftp_do_more(struct connectdata *conn, bool *complete) | ||||
| { | ||||
|   struct SessionHandle *data=conn->data; | ||||
|   struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|   CURLcode result = CURLE_OK; | ||||
|   bool connected = FALSE; | ||||
|  | ||||
|   /* the ftp struct is inited in ftp_connect() */ | ||||
|   struct FTP *ftp = data->state.proto.ftp; | ||||
|  | ||||
|   DEBUGF(infof(data, "DO-MORE phase starts\n")); | ||||
|   /* if the second connection isn't done yet, wait for it */ | ||||
|   if(!conn->bits.tcpconnect[SECONDARYSOCKET]) { | ||||
|     result = Curl_is_connected(conn, SECONDARYSOCKET, &connected); | ||||
|  | ||||
|     /* Ready to do more? */ | ||||
|     if(connected) { | ||||
|       DEBUGF(infof(data, "DO-MORE connected phase starts\n")); | ||||
|     } | ||||
|     else | ||||
|       return result; | ||||
|   } | ||||
|  | ||||
|   if(ftp->transfer <= FTPTRANSFER_INFO) { | ||||
|     /* a transfer is about to take place, or if not a file name was given | ||||
|        so we'll do a SIZE on it later and then we need the right TYPE first */ | ||||
|  | ||||
|     if(data->set.upload) { | ||||
|     if(ftpc->wait_data_conn == TRUE) { | ||||
|       bool serv_conned; | ||||
|  | ||||
|       result = ReceivedServerConnect(conn, &serv_conned); | ||||
|       if(result) | ||||
|         return result; /* Failed to accept data connection */ | ||||
|  | ||||
|       if(serv_conned) { | ||||
|         /* It looks data connection is established */ | ||||
|         result = AcceptServerConnect(conn); | ||||
|         ftpc->wait_data_conn = FALSE; | ||||
|         if(result == CURLE_OK) | ||||
|           result = InitiateTransfer(conn); | ||||
|       } | ||||
|     } | ||||
|     else if(data->set.upload) { | ||||
|       result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE); | ||||
|       if(result) | ||||
|         return result; | ||||
| @@ -3463,8 +3744,11 @@ static CURLcode ftp_nextconnect(struct connectdata *conn) | ||||
|        too! */ | ||||
|     Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); | ||||
|  | ||||
|   /* end of transfer */ | ||||
|   if(!ftpc->wait_data_conn) { | ||||
|     /* no waiting for the data connection so this is now complete */ | ||||
|     *complete = TRUE; | ||||
|     DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result)); | ||||
|   } | ||||
|  | ||||
|   return result; | ||||
| } | ||||
| @@ -3663,8 +3947,7 @@ static CURLcode wc_statemach(struct connectdata *conn) | ||||
|     strcat(tmp_path, finfo->filename); | ||||
|     /* switch default "state.pathbuffer" and tmp_path, good to see | ||||
|        ftp_parse_url_path function to understand this trick */ | ||||
|     if(conn->data->state.pathbuffer) | ||||
|       free(conn->data->state.pathbuffer); | ||||
|     Curl_safefree(conn->data->state.pathbuffer); | ||||
|     conn->data->state.pathbuffer = tmp_path; | ||||
|     conn->data->state.path = tmp_path; | ||||
|  | ||||
| @@ -3745,8 +4028,10 @@ static CURLcode wc_statemach(struct connectdata *conn) | ||||
| static CURLcode ftp_do(struct connectdata *conn, bool *done) | ||||
| { | ||||
|   CURLcode retcode = CURLE_OK; | ||||
|   struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|  | ||||
|   *done = FALSE; /* default to false */ | ||||
|   ftpc->wait_data_conn = FALSE; /* default to no such wait */ | ||||
|  | ||||
|   /* | ||||
|     Since connections can be re-used between SessionHandles, this might be a | ||||
| @@ -3853,7 +4138,16 @@ static CURLcode ftp_quit(struct connectdata *conn) | ||||
|   CURLcode result = CURLE_OK; | ||||
|  | ||||
|   if(conn->proto.ftpc.ctl_valid) { | ||||
|     PPSENDF(&conn->proto.ftpc.pp, "QUIT", NULL); | ||||
|     result = Curl_pp_sendf(&conn->proto.ftpc.pp, "QUIT", NULL); | ||||
|     if(result) { | ||||
|       failf(conn->data, "Failure sending QUIT command: %s", | ||||
|             curl_easy_strerror(result)); | ||||
|       conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */ | ||||
|       conn->bits.close = TRUE; /* mark for connection closure */ | ||||
|       state(conn, FTP_STOP); | ||||
|       return result; | ||||
|     } | ||||
|  | ||||
|     state(conn, FTP_QUIT); | ||||
|  | ||||
|     result = ftp_easy_statemach(conn); | ||||
| @@ -4107,8 +4401,10 @@ static CURLcode ftp_dophase_done(struct connectdata *conn, | ||||
|   struct FTP *ftp = conn->data->state.proto.ftp; | ||||
|   struct ftp_conn *ftpc = &conn->proto.ftpc; | ||||
|  | ||||
|   if(connected) | ||||
|     result = ftp_nextconnect(conn); | ||||
|   if(connected) { | ||||
|     bool completed; | ||||
|     result = ftp_do_more(conn, &completed); | ||||
|   } | ||||
|  | ||||
|   if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) { | ||||
|     /* Failure detected, close the second socket if it was created already */ | ||||
|   | ||||
| @@ -139,6 +139,7 @@ struct ftp_conn { | ||||
|                        already has been done */ | ||||
|   bool cwdfail;     /* set TRUE if a CWD command fails, as then we must prevent | ||||
|                        caching the current directory */ | ||||
|   bool wait_data_conn; /* this is set TRUE if data connection is waited */ | ||||
|   char *prevpath;   /* conn->path from the previous transfer */ | ||||
|   char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a | ||||
|                         and others (A/I or zero) */ | ||||
| @@ -146,10 +147,15 @@ struct ftp_conn { | ||||
|   int count2; /* general purpose counter for the state machine */ | ||||
|   int count3; /* general purpose counter for the state machine */ | ||||
|   ftpstate state; /* always use ftp.c:state() to change state! */ | ||||
|   ftpstate state_saved; /* transfer type saved to be reloaded after | ||||
|                            data connection is established */ | ||||
|   curl_off_t retr_size_saved; /* Size of retrieved file saved */ | ||||
|   char * server_os;     /* The target server operating system. */ | ||||
|   curl_off_t known_filesize; /* file size is different from -1, if wildcard | ||||
|                                 LIST parsing was done and wc_statemach set | ||||
|                                 it */ | ||||
| }; | ||||
|  | ||||
| #define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */ | ||||
|  | ||||
| #endif /* HEADER_CURL_FTP_H */ | ||||
|   | ||||
| @@ -46,6 +46,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data) | ||||
|  | ||||
|   pro->t_nslookup = 0; | ||||
|   pro->t_connect = 0; | ||||
|   pro->t_appconnect = 0; | ||||
|   pro->t_pretransfer = 0; | ||||
|   pro->t_starttransfer = 0; | ||||
|   pro->timespent = 0; | ||||
|   | ||||
| @@ -97,6 +97,7 @@ const struct Curl_handler Curl_handler_gopher = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
|   | ||||
							
								
								
									
										47
									
								
								lib/gtls.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								lib/gtls.c
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -34,7 +34,9 @@ | ||||
|  | ||||
| #include <gnutls/gnutls.h> | ||||
| #include <gnutls/x509.h> | ||||
| #ifndef USE_GNUTLS_NETTLE | ||||
| #include <gcrypt.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| @@ -78,6 +80,17 @@ static void tls_log_func(int level, const char *str) | ||||
| #endif | ||||
| static bool gtls_inited = FALSE; | ||||
|  | ||||
| #if defined(GNUTLS_VERSION_NUMBER) | ||||
| #  if (GNUTLS_VERSION_NUMBER >= 0x020c00) | ||||
| #    undef gnutls_transport_set_lowat | ||||
| #    define gnutls_transport_set_lowat(A,B) Curl_nop_stmt | ||||
| #    define USE_GNUTLS_PRIORITY_SET_DIRECT 1 | ||||
| #  endif | ||||
| #  if (GNUTLS_VERSION_NUMBER >= 0x020c03) | ||||
| #    define GNUTLS_MAPS_WINSOCK_ERRORS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Custom push and pull callback functions used by GNU TLS to read and write | ||||
|  * to the socket.  These functions are simple wrappers to send() and recv() | ||||
| @@ -95,9 +108,13 @@ static bool gtls_inited = FALSE; | ||||
|  * resort global errno variable using gnutls_transport_set_global_errno, | ||||
|  * with a transport agnostic error value. This implies that some winsock | ||||
|  * error translation must take place in these callbacks. | ||||
|  * | ||||
|  * Paragraph above applies to GNU TLS versions older than 2.12.3, since | ||||
|  * this version GNU TLS does its own internal winsock error translation | ||||
|  * using system_errno() function. | ||||
|  */ | ||||
|  | ||||
| #ifdef USE_WINSOCK | ||||
| #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) | ||||
| #  define gtls_EINTR  4 | ||||
| #  define gtls_EIO    5 | ||||
| #  define gtls_EAGAIN 11 | ||||
| @@ -118,7 +135,7 @@ static int gtls_mapped_sockerrno(void) | ||||
| static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) | ||||
| { | ||||
|   ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len); | ||||
| #ifdef USE_WINSOCK | ||||
| #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) | ||||
|   if(ret < 0) | ||||
|     gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); | ||||
| #endif | ||||
| @@ -128,7 +145,7 @@ static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) | ||||
| static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len) | ||||
| { | ||||
|   ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len); | ||||
| #ifdef USE_WINSOCK | ||||
| #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) | ||||
|   if(ret < 0) | ||||
|     gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); | ||||
| #endif | ||||
| @@ -186,7 +203,7 @@ static void showtime(struct SessionHandle *data, | ||||
|            tm->tm_hour, | ||||
|            tm->tm_min, | ||||
|            tm->tm_sec); | ||||
|   infof(data, "%s", data->state.buffer); | ||||
|   infof(data, "%s\n", data->state.buffer); | ||||
| } | ||||
|  | ||||
| static gnutls_datum load_file (const char *file) | ||||
| @@ -309,7 +326,9 @@ static CURLcode | ||||
| gtls_connect_step1(struct connectdata *conn, | ||||
|                    int sockindex) | ||||
| { | ||||
| #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT | ||||
|   static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 }; | ||||
| #endif | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   gnutls_session session; | ||||
|   int rc; | ||||
| @@ -429,18 +448,32 @@ gtls_connect_step1(struct connectdata *conn, | ||||
|     return CURLE_SSL_CONNECT_ERROR; | ||||
|  | ||||
|   if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) { | ||||
| #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT | ||||
|     static const int protocol_priority[] = { GNUTLS_SSL3, 0 }; | ||||
|     gnutls_protocol_set_priority(session, protocol_priority); | ||||
|     rc = gnutls_protocol_set_priority(session, protocol_priority); | ||||
| #else | ||||
|     const char *err; | ||||
|     /* the combination of the cipher ARCFOUR with SSL 3.0 and TLS 1.0 is not | ||||
|        vulnerable to attacks such as the BEAST, why this code now explicitly | ||||
|        asks for that | ||||
|     */ | ||||
|     rc = gnutls_priority_set_direct(session, | ||||
|                                     "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0:" | ||||
|                                     "-CIPHER-ALL:+ARCFOUR-128", | ||||
|                                     &err); | ||||
| #endif | ||||
|     if(rc != GNUTLS_E_SUCCESS) | ||||
|       return CURLE_SSL_CONNECT_ERROR; | ||||
|   } | ||||
|  | ||||
| #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT | ||||
|   /* Sets the priority on the certificate types supported by gnutls. Priority | ||||
|      is higher for types specified before others. After specifying the types | ||||
|      you want, you must append a 0. */ | ||||
|   rc = gnutls_certificate_type_set_priority(session, cert_type_priority); | ||||
|   if(rc != GNUTLS_E_SUCCESS) | ||||
|     return CURLE_SSL_CONNECT_ERROR; | ||||
| #endif | ||||
|  | ||||
|   if(data->set.str[STRING_CERT]) { | ||||
|     if(gnutls_certificate_set_x509_key_file( | ||||
| @@ -1010,7 +1043,9 @@ int Curl_gtls_seed(struct SessionHandle *data) | ||||
|   static bool ssl_seeded = FALSE; | ||||
|  | ||||
|   /* Quickly add a bit of entropy */ | ||||
| #ifndef USE_GNUTLS_NETTLE | ||||
|   gcry_fast_random_poll(); | ||||
| #endif | ||||
|  | ||||
|   if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] || | ||||
|      data->set.str[STRING_SSL_EGDSOCKET]) { | ||||
|   | ||||
							
								
								
									
										26
									
								
								lib/hash.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								lib/hash.c
									
									
									
									
									
								
							| @@ -38,11 +38,14 @@ hash_element_dtor(void *user, void *element) | ||||
|   struct curl_hash *h = (struct curl_hash *) user; | ||||
|   struct curl_hash_element *e = (struct curl_hash_element *) element; | ||||
|  | ||||
|   if(e->key) | ||||
|     free(e->key); | ||||
|   Curl_safefree(e->key); | ||||
|  | ||||
|   if(e->ptr) | ||||
|   if(e->ptr) { | ||||
|     h->dtor(e->ptr); | ||||
|     e->ptr = NULL; | ||||
|   } | ||||
|  | ||||
|   e->key_len = 0; | ||||
|  | ||||
|   free(e); | ||||
| } | ||||
| @@ -72,17 +75,23 @@ Curl_hash_init(struct curl_hash *h, | ||||
|     for(i = 0; i < slots; ++i) { | ||||
|       h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); | ||||
|       if(!h->table[i]) { | ||||
|         while(i--) | ||||
|         while(i--) { | ||||
|           Curl_llist_destroy(h->table[i], NULL); | ||||
|           h->table[i] = NULL; | ||||
|         } | ||||
|         free(h->table); | ||||
|         h->table = NULL; | ||||
|         h->slots = 0; | ||||
|         return 1; /* failure */ | ||||
|       } | ||||
|     } | ||||
|     return 0; /* fine */ | ||||
|   } | ||||
|   else | ||||
|   else { | ||||
|     h->slots = 0; | ||||
|     return 1; /* failure */ | ||||
|   } | ||||
| } | ||||
|  | ||||
| struct curl_hash * | ||||
| Curl_hash_alloc(int slots, | ||||
| @@ -187,6 +196,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) | ||||
|     he = le->ptr; | ||||
|     if(h->comp_func(he->key, he->key_len, key, key_len)) { | ||||
|       Curl_llist_remove(l, le, (void *) h); | ||||
|       --h->size; | ||||
|       return 0; | ||||
|     } | ||||
|   } | ||||
| @@ -240,6 +250,9 @@ Curl_hash_clean(struct curl_hash *h) | ||||
|   } | ||||
|  | ||||
|   free(h->table); | ||||
|   h->table = NULL; | ||||
|   h->size = 0; | ||||
|   h->slots = 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -251,6 +264,9 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, | ||||
|   struct curl_llist *list; | ||||
|   int i; | ||||
|  | ||||
|   if(!h) | ||||
|     return; | ||||
|  | ||||
|   for(i = 0; i < h->slots; ++i) { | ||||
|     list = h->table[i]; | ||||
|     le = list->head; /* get first list entry */ | ||||
|   | ||||
							
								
								
									
										104
									
								
								lib/hostip.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								lib/hostip.c
									
									
									
									
									
								
							| @@ -201,14 +201,23 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize) | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Return a hostcache id string for the providing host + port, to be used by | ||||
|  * Return a hostcache id string for the provided host + port, to be used by | ||||
|  * the DNS caching. | ||||
|  */ | ||||
| static char * | ||||
| create_hostcache_id(const char *server, int port) | ||||
| create_hostcache_id(const char *name, int port) | ||||
| { | ||||
|   /* create and return the new allocated entry */ | ||||
|   return aprintf("%s:%d", server, port); | ||||
|   char *id = aprintf("%s:%d", name, port); | ||||
|   char *ptr = id; | ||||
|   if(ptr) { | ||||
|     /* lower case the name part */ | ||||
|     while(*ptr && (*ptr != ':')) { | ||||
|       *ptr = (char)TOLOWER(*ptr); | ||||
|       ptr++; | ||||
|     } | ||||
|   } | ||||
|   return id; | ||||
| } | ||||
|  | ||||
| struct hostcache_prune_data { | ||||
| @@ -721,4 +730,93 @@ struct curl_hash *Curl_mk_dnscache(void) | ||||
|   return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry); | ||||
| } | ||||
|  | ||||
| static int hostcache_inuse(void *data, void *hc) | ||||
| { | ||||
|   struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc; | ||||
|  | ||||
|   if(c->inuse == 1) | ||||
|     Curl_resolv_unlock(data, c); | ||||
|  | ||||
|   return 1; /* free all entries */ | ||||
| } | ||||
|  | ||||
| void Curl_hostcache_destroy(struct SessionHandle *data) | ||||
| { | ||||
|   /* Entries added to the hostcache with the CURLOPT_RESOLVE function are | ||||
|    * still present in the cache with the inuse counter set to 1. Detect them | ||||
|    * and cleanup! | ||||
|    */ | ||||
|   Curl_hash_clean_with_criterium(data->dns.hostcache, data, hostcache_inuse); | ||||
|  | ||||
|   Curl_hash_destroy(data->dns.hostcache); | ||||
|   data->dns.hostcachetype = HCACHE_NONE; | ||||
|   data->dns.hostcache = NULL; | ||||
| } | ||||
|  | ||||
| CURLcode Curl_loadhostpairs(struct SessionHandle *data) | ||||
| { | ||||
|   struct curl_slist *hostp; | ||||
|   char hostname[256]; | ||||
|   char address[256]; | ||||
|   int port; | ||||
|  | ||||
|   for(hostp = data->change.resolve; hostp; hostp = hostp->next ) { | ||||
|     if(!hostp->data) | ||||
|       continue; | ||||
|     if(hostp->data[0] == '-') { | ||||
|       /* TODO: mark an entry for removal */ | ||||
|     } | ||||
|     else if(3 == sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port, | ||||
|                         address)) { | ||||
|       struct Curl_dns_entry *dns; | ||||
|       Curl_addrinfo *addr; | ||||
|       char *entry_id; | ||||
|       size_t entry_len; | ||||
|  | ||||
|       addr = Curl_str2addr(address, port); | ||||
|       if(!addr) { | ||||
|         infof(data, "Resolve %s found illegal!\n", hostp->data); | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       /* Create an entry id, based upon the hostname and port */ | ||||
|       entry_id = create_hostcache_id(hostname, port); | ||||
|       /* If we can't create the entry id, fail */ | ||||
|       if(!entry_id) { | ||||
|         Curl_freeaddrinfo(addr); | ||||
|         return CURLE_OUT_OF_MEMORY; | ||||
|       } | ||||
|  | ||||
|       entry_len = strlen(entry_id); | ||||
|  | ||||
|       if(data->share) | ||||
|         Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); | ||||
|  | ||||
|       /* See if its already in our dns cache */ | ||||
|       dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1); | ||||
|  | ||||
|       /* free the allocated entry_id again */ | ||||
|       free(entry_id); | ||||
|  | ||||
|       if(!dns) | ||||
|         /* if not in the cache already, put this host in the cache */ | ||||
|         dns = Curl_cache_addr(data, addr, hostname, port); | ||||
|       else | ||||
|         /* this is a duplicate, free it again */ | ||||
|         Curl_freeaddrinfo(addr); | ||||
|  | ||||
|       if(data->share) | ||||
|         Curl_share_unlock(data, CURL_LOCK_DATA_DNS); | ||||
|  | ||||
|       if(!dns) { | ||||
|         Curl_freeaddrinfo(addr); | ||||
|         return CURLE_OUT_OF_MEMORY; | ||||
|       } | ||||
|       infof(data, "Added %s:%d:%s to DNS cache\n", | ||||
|             hostname, port, address); | ||||
|     } | ||||
|   } | ||||
|   data->change.resolve = NULL; /* dealt with now */ | ||||
|  | ||||
|   return CURLE_OK; | ||||
| } | ||||
|   | ||||
							
								
								
									
										12
									
								
								lib/hostip.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								lib/hostip.h
									
									
									
									
									
								
							| @@ -195,4 +195,16 @@ Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr, | ||||
| extern sigjmp_buf curl_jmpenv; | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Function provided by the resolver backend to set DNS servers to use. | ||||
|  */ | ||||
| CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers); | ||||
|  | ||||
| /* | ||||
|  * Destroy the hostcache of this handle. | ||||
|  */ | ||||
| void Curl_hostcache_destroy(struct SessionHandle *data); | ||||
|  | ||||
| CURLcode Curl_loadhostpairs(struct SessionHandle *data); | ||||
|  | ||||
| #endif /* HEADER_CURL_HOSTIP_H */ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -119,6 +119,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, | ||||
| #endif /* CURLRES_SYNCH */ | ||||
| #endif /* CURLRES_IPV4 */ | ||||
|  | ||||
| #if defined(CURLRES_IPV4) && !defined(CURLRES_ARES) | ||||
|  | ||||
| /* | ||||
|  * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. | ||||
|  * | ||||
| @@ -311,3 +313,4 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, | ||||
|  | ||||
|   return ai; | ||||
| } | ||||
| #endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */ | ||||
|   | ||||
| @@ -66,5 +66,16 @@ | ||||
|  **********************************************************************/ | ||||
| #ifdef CURLRES_SYNCH | ||||
|  | ||||
| /* | ||||
|  * Function provided by the resolver backend to set DNS servers to use. | ||||
|  */ | ||||
| CURLcode Curl_set_dns_servers(struct SessionHandle *data, | ||||
|                               char *servers) | ||||
| { | ||||
|   (void)data; | ||||
|   (void)servers; | ||||
|   return CURLE_NOT_BUILT_IN; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif /* truly sync */ | ||||
|   | ||||
							
								
								
									
										70
									
								
								lib/http.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								lib/http.c
									
									
									
									
									
								
							| @@ -118,6 +118,7 @@ const struct Curl_handler Curl_handler_http = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   http_getsock_do,                      /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -141,6 +142,7 @@ const struct Curl_handler Curl_handler_https = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   https_getsock,                        /* proto_getsock */ | ||||
|   http_getsock_do,                      /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -546,7 +548,7 @@ output_auth_headers(struct connectdata *conn, | ||||
|   } | ||||
|   else | ||||
| #endif | ||||
| #ifdef NTLM_WB_ENABLED | ||||
| #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED) | ||||
|   if(authstatus->picked == CURLAUTH_NTLM_WB) { | ||||
|     auth="NTLM_WB"; | ||||
|     result = Curl_output_ntlm_wb(conn, proxy); | ||||
| @@ -731,6 +733,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, | ||||
|    * | ||||
|    */ | ||||
|  | ||||
|   while(*start) { | ||||
| #ifdef USE_HTTP_NEGOTIATE | ||||
|     if(checkprefix("GSS-Negotiate", start) || | ||||
|        checkprefix("Negotiate", start)) { | ||||
| @@ -738,14 +741,15 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, | ||||
|       *availp |= CURLAUTH_GSSNEGOTIATE; | ||||
|       authp->avail |= CURLAUTH_GSSNEGOTIATE; | ||||
|  | ||||
|       if(authp->picked == CURLAUTH_GSSNEGOTIATE) { | ||||
|         if(data->state.negotiate.state == GSS_AUTHSENT) { | ||||
|       /* if we sent GSS authentication in the outgoing request and we get this | ||||
|          back, we're in trouble */ | ||||
|           /* if we sent GSS authentication in the outgoing request and we get | ||||
|              this back, we're in trouble */ | ||||
|           infof(data, "Authentication problem. Ignoring this.\n"); | ||||
|           data->state.authproblem = TRUE; | ||||
|         } | ||||
|         else { | ||||
|       neg = Curl_input_negotiate(conn, (httpcode == 407)?TRUE:FALSE, start); | ||||
|           neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start); | ||||
|           if(neg == 0) { | ||||
|             DEBUGASSERT(!data->req.newurl); | ||||
|             data->req.newurl = strdup(data->change.url); | ||||
| @@ -755,7 +759,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, | ||||
|             /* we received GSS auth info and we dealt with it fine */ | ||||
|             data->state.negotiate.state = GSS_AUTHRECV; | ||||
|           } | ||||
|       else { | ||||
|           else | ||||
|             data->state.authproblem = TRUE; | ||||
|         } | ||||
|       } | ||||
| @@ -816,7 +820,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, | ||||
|  | ||||
|             /* We call this function on input Digest headers even if Digest | ||||
|              * authentication isn't activated yet, as we need to store the | ||||
|            * incoming data from this header in case we are gonna use Digest. */ | ||||
|              * incoming data from this header in case we are gonna use | ||||
|              * Digest. */ | ||||
|             dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start); | ||||
|  | ||||
|             if(CURLDIGEST_FINE != dig) { | ||||
| @@ -840,6 +845,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, | ||||
|             } | ||||
|           } | ||||
|  | ||||
|     /* there may be multiple methods on one line, so keep reading */ | ||||
|     while(*start && *start != ',') /* read up to the next comma */ | ||||
|       start++; | ||||
|     if(*start == ',') /* if we're on a comma, skip it */ | ||||
|       start++; | ||||
|     while(*start && ISSPACE(*start)) | ||||
|       start++; | ||||
|   } | ||||
|   return CURLE_OK; | ||||
| } | ||||
|  | ||||
| @@ -1559,6 +1572,31 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       ptr = strchr(headers->data, ';'); | ||||
|       if(ptr) { | ||||
|  | ||||
|         ptr++; /* pass the semicolon */ | ||||
|         while(*ptr && ISSPACE(*ptr)) | ||||
|           ptr++; | ||||
|  | ||||
|         if(*ptr) { | ||||
|           /* this may be used for something else in the future */ | ||||
|         } | ||||
|         else { | ||||
|           if(*(--ptr) == ';') { | ||||
|             CURLcode result; | ||||
|  | ||||
|             /* send no-value custom header if terminated by semicolon */ | ||||
|             *ptr = ':'; | ||||
|             result = Curl_add_bufferf(req_buffer, "%s\r\n", | ||||
|                                              headers->data); | ||||
|             if(result) | ||||
|               return result; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     headers = headers->next; | ||||
|   } | ||||
|   return CURLE_OK; | ||||
| @@ -1887,8 +1925,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) | ||||
|           memcpy(newurl + newlen + (ptr - url), | ||||
|                  ptr + currlen, /* copy the trailing zero byte too */ | ||||
|                  urllen - (ptr-url) - currlen + 1); | ||||
|           if(data->change.url_alloc) | ||||
|             free(data->change.url); | ||||
|           if(data->change.url_alloc) { | ||||
|             Curl_safefree(data->change.url); | ||||
|             data->change.url_alloc = FALSE; | ||||
|           } | ||||
|           data->change.url = newurl; | ||||
|           data->change.url_alloc = TRUE; | ||||
|         } | ||||
| @@ -2091,7 +2131,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) | ||||
|   if(result) | ||||
|     return result; | ||||
|  | ||||
|   result = Curl_add_bufferf(req_buffer, | ||||
|   result = | ||||
|     Curl_add_bufferf(req_buffer, | ||||
|                      "%s" /* ftp typecode (;type=x) */ | ||||
|                      " HTTP/%s\r\n" /* HTTP version */ | ||||
|                      "%s" /* proxyuserpwd */ | ||||
| @@ -2114,9 +2155,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) | ||||
|                      (data->state.use_range && conn->allocptr.rangeline)? | ||||
|                      conn->allocptr.rangeline:"", | ||||
|                      (data->set.str[STRING_USERAGENT] && | ||||
|                  *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)? | ||||
|                       *data->set.str[STRING_USERAGENT] && | ||||
|                       conn->allocptr.uagent)? | ||||
|                      conn->allocptr.uagent:"", | ||||
|                 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ | ||||
|                      (conn->allocptr.host?conn->allocptr.host:""), | ||||
|                      http->p_accept?http->p_accept:"", | ||||
|                      conn->allocptr.te?conn->allocptr.te:"", | ||||
|                      (data->set.str[STRING_ENCODING] && | ||||
| @@ -2252,7 +2294,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) | ||||
|  | ||||
|     http->sending = HTTPSEND_BODY; | ||||
|  | ||||
|     if(!data->req.upload_chunky) { | ||||
|     if(!data->req.upload_chunky && | ||||
|        !Curl_checkheaders(data, "Content-Length:")) { | ||||
|       /* only add Content-Length if not uploading chunked */ | ||||
|       result = Curl_add_bufferf(req_buffer, | ||||
|                                 "Content-Length: %" FORMAT_OFF_T "\r\n", | ||||
| @@ -2323,7 +2366,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) | ||||
|     else | ||||
|       postsize = data->set.infilesize; | ||||
|  | ||||
|     if((postsize != -1) && !data->req.upload_chunky) { | ||||
|     if((postsize != -1) && !data->req.upload_chunky && | ||||
|        !Curl_checkheaders(data, "Content-Length:")) { | ||||
|       /* only add Content-Length if not uploading chunked */ | ||||
|       result = Curl_add_bufferf(req_buffer, | ||||
|                                 "Content-Length: %" FORMAT_OFF_T "\r\n", | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -124,7 +124,7 @@ log_gss_error(struct connectdata *conn, OM_uint32 error_status, | ||||
|     gss_release_buffer(&min_stat, &status_string); | ||||
|   } while(!GSS_ERROR(maj_stat) && msg_ctx != 0); | ||||
|  | ||||
|   infof(conn->data, "%s", buf); | ||||
|   infof(conn->data, "%s\n", buf); | ||||
| } | ||||
|  | ||||
| /* returning zero (0) means success, everything else is treated as "failure" | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -29,6 +29,7 @@ | ||||
| #include "urldata.h" | ||||
| #include "sendf.h" | ||||
| #include "rawstr.h" | ||||
| #include "warnless.h" | ||||
| #include "curl_base64.h" | ||||
| #include "http_negotiate.h" | ||||
| #include "curl_memory.h" | ||||
| @@ -189,7 +190,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy, | ||||
|   out_buff_desc.cBuffers  = 1; | ||||
|   out_buff_desc.pBuffers  = &out_sec_buff; | ||||
|  | ||||
|   out_sec_buff.cbBuffer   = neg_ctx->max_token_length; | ||||
|   out_sec_buff.cbBuffer   = curlx_uztoul(neg_ctx->max_token_length); | ||||
|   out_sec_buff.BufferType = SECBUFFER_TOKEN; | ||||
|   out_sec_buff.pvBuffer   = neg_ctx->output_token; | ||||
|  | ||||
| @@ -197,9 +198,9 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy, | ||||
|   if(input_token) { | ||||
|     in_buff_desc.ulVersion = 0; | ||||
|     in_buff_desc.cBuffers  = 1; | ||||
|     in_buff_desc.pBuffers  = &out_sec_buff; | ||||
|     in_buff_desc.pBuffers  = &in_sec_buff; | ||||
|  | ||||
|     in_sec_buff.cbBuffer   = input_token_len; | ||||
|     in_sec_buff.cbBuffer   = curlx_uztoul(input_token_len); | ||||
|     in_sec_buff.BufferType = SECBUFFER_TOKEN; | ||||
|     in_sec_buff.pvBuffer   = input_token; | ||||
|   } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -202,11 +202,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, | ||||
|       else { | ||||
|         DEBUGF(infof(data, | ||||
|                      "Multi mode finished polling for response from " | ||||
|                      "proxy CONNECT.")); | ||||
|                      "proxy CONNECT\n")); | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       DEBUGF(infof(data, "Easy mode waiting response from proxy CONNECT.")); | ||||
|       DEBUGF(infof(data, "Easy mode waiting response from proxy CONNECT\n")); | ||||
|     } | ||||
|  | ||||
|     /* at this point, either: | ||||
| @@ -409,8 +409,15 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, | ||||
|                         keepon=FALSE; | ||||
|                       } | ||||
|                     } | ||||
|                     else | ||||
|                     else { | ||||
|                       keepon = FALSE; | ||||
|                       if(200 == data->info.httpproxycode) { | ||||
|                         if(gotbytes - (i+1)) | ||||
|                           failf(data, "Proxy CONNECT followed by %zd bytes " | ||||
|                                 "of opaque data. Data ignored (known bug #39)", | ||||
|                                 gotbytes - (i+1)); | ||||
|                       } | ||||
|                     } | ||||
|                     break; /* breaks out of for-loop, not switch() */ | ||||
|                   } | ||||
|  | ||||
|   | ||||
							
								
								
									
										47
									
								
								lib/if2ip.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								lib/if2ip.c
									
									
									
									
									
								
							| @@ -71,7 +71,25 @@ | ||||
|  | ||||
| #if defined(HAVE_GETIFADDRS) | ||||
|  | ||||
| char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
| bool Curl_if_is_interface_name(const char *interf) | ||||
| { | ||||
|   bool result = FALSE; | ||||
|  | ||||
|   struct ifaddrs *iface, *head; | ||||
|  | ||||
|   if(getifaddrs(&head) >= 0) { | ||||
|     for(iface=head; iface != NULL; iface=iface->ifa_next) { | ||||
|       if(curl_strequal(iface->ifa_name, interf)) { | ||||
|         result = TRUE; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     freeifaddrs(head); | ||||
|   } | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size) | ||||
| { | ||||
|   struct ifaddrs *iface, *head; | ||||
|   char *ip = NULL; | ||||
| @@ -80,7 +98,7 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
|     for(iface=head; iface != NULL; iface=iface->ifa_next) { | ||||
|       if((iface->ifa_addr != NULL) && | ||||
|          (iface->ifa_addr->sa_family == af) && | ||||
|          curl_strequal(iface->ifa_name, interface)) { | ||||
|          curl_strequal(iface->ifa_name, interf)) { | ||||
|         void *addr; | ||||
|         char scope[12]=""; | ||||
| #ifdef ENABLE_IPV6 | ||||
| @@ -109,7 +127,17 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
|  | ||||
| #elif defined(HAVE_IOCTL_SIOCGIFADDR) | ||||
|  | ||||
| char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
| bool Curl_if_is_interface_name(const char *interf) | ||||
| { | ||||
|   /* This is here just to support the old interfaces */ | ||||
|   char buf[256]; | ||||
|  | ||||
|   char *ip = Curl_if2ip(AF_INET, interf, buf, sizeof(buf)); | ||||
|  | ||||
|   return (ip != NULL) ? TRUE : FALSE; | ||||
| } | ||||
|  | ||||
| char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size) | ||||
| { | ||||
|   struct ifreq req; | ||||
|   struct in_addr in; | ||||
| @@ -118,10 +146,10 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
|   size_t len; | ||||
|   char *ip; | ||||
|  | ||||
|   if(!interface || (af != AF_INET)) | ||||
|   if(!interf || (af != AF_INET)) | ||||
|     return NULL; | ||||
|  | ||||
|   len = strlen(interface); | ||||
|   len = strlen(interf); | ||||
|   if(len >= sizeof(req.ifr_name)) | ||||
|     return NULL; | ||||
|  | ||||
| @@ -130,7 +158,7 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
|     return NULL; | ||||
|  | ||||
|   memset(&req, 0, sizeof(req)); | ||||
|   memcpy(req.ifr_name, interface, len+1); | ||||
|   memcpy(req.ifr_name, interf, len+1); | ||||
|   req.ifr_addr.sa_family = AF_INET; | ||||
|  | ||||
|   if(ioctl(dummy, SIOCGIFADDR, &req) < 0) { | ||||
| @@ -148,6 +176,13 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) | ||||
|  | ||||
| #else | ||||
|  | ||||
| bool Curl_if_is_interface_name(const char *interf) | ||||
| { | ||||
|   (void) interf; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size) | ||||
| { | ||||
|     (void) af; | ||||
|   | ||||
							
								
								
									
										11
									
								
								lib/if2ip.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								lib/if2ip.h
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| #ifndef __IF2IP_H | ||||
| #define __IF2IP_H | ||||
| #ifndef HEADER_CURL_IF2IP_H | ||||
| #define HEADER_CURL_IF2IP_H | ||||
| /*************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
| @@ -7,7 +7,7 @@ | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
|  * | ||||
|  * This software is licensed as described in the file COPYING, which | ||||
|  * you should have received as part of this distribution. The terms | ||||
| @@ -23,7 +23,8 @@ | ||||
|  ***************************************************************************/ | ||||
| #include "setup.h" | ||||
|  | ||||
| extern char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size); | ||||
| bool Curl_if_is_interface_name(const char *interf); | ||||
| char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size); | ||||
|  | ||||
| #ifdef __INTERIX | ||||
| #include <sys/socket.h> | ||||
| @@ -62,4 +63,4 @@ struct ifreq { | ||||
| #define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */ | ||||
| #endif /* interix */ | ||||
|  | ||||
| #endif | ||||
| #endif /* HEADER_CURL_IF2IP_H */ | ||||
|   | ||||
							
								
								
									
										25
									
								
								lib/imap.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								lib/imap.c
									
									
									
									
									
								
							| @@ -119,12 +119,14 @@ const struct Curl_handler Curl_handler_imap = { | ||||
|   imap_doing,                       /* doing */ | ||||
|   imap_getsock,                     /* proto_getsock */ | ||||
|   imap_getsock,                     /* doing_getsock */ | ||||
|   ZERO_NULL,                        /* domore_getsock */ | ||||
|   ZERO_NULL,                        /* perform_getsock */ | ||||
|   imap_disconnect,                  /* disconnect */ | ||||
|   ZERO_NULL,                        /* readwrite */ | ||||
|   PORT_IMAP,                        /* defport */ | ||||
|   CURLPROTO_IMAP,                   /* protocol */ | ||||
|   PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */ | ||||
|   PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | ||||
|   | PROTOPT_NOURLQUERY              /* flags */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -144,12 +146,14 @@ const struct Curl_handler Curl_handler_imaps = { | ||||
|   imap_doing,                       /* doing */ | ||||
|   imap_getsock,                     /* proto_getsock */ | ||||
|   imap_getsock,                     /* doing_getsock */ | ||||
|   ZERO_NULL,                        /* domore_getsock */ | ||||
|   ZERO_NULL,                        /* perform_getsock */ | ||||
|   imap_disconnect,                  /* disconnect */ | ||||
|   ZERO_NULL,                        /* readwrite */ | ||||
|   PORT_IMAPS,                       /* defport */ | ||||
|   CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */ | ||||
|   PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD /* flags */ | ||||
|   PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD | ||||
|   | PROTOPT_NOURLQUERY              /* flags */ | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| @@ -169,6 +173,7 @@ static const struct Curl_handler Curl_handler_imap_proxy = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -194,6 +199,7 @@ static const struct Curl_handler Curl_handler_imaps_proxy = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -348,8 +354,12 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn, | ||||
|   (void)instate; /* no use for this yet */ | ||||
|  | ||||
|   if(imapcode != 'O') { | ||||
|     if(data->set.use_ssl != CURLUSESSL_TRY) { | ||||
|       failf(data, "STARTTLS denied. %c", imapcode); | ||||
|     result = CURLE_LOGIN_DENIED; | ||||
|       result = CURLE_USE_SSL_FAILED; | ||||
|     } | ||||
|     else | ||||
|       result = imap_state_login(conn); | ||||
|   } | ||||
|   else { | ||||
|     if(data->state.used_interface == Curl_if_multi) { | ||||
| @@ -576,7 +586,7 @@ static CURLcode imap_statemach_act(struct connectdata *conn) | ||||
|       return CURLE_FTP_WEIRD_SERVER_REPLY; | ||||
|     } | ||||
|  | ||||
|     if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) { | ||||
|     if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { | ||||
|       /* We don't have a SSL/TLS connection yet, but SSL is requested. Switch | ||||
|          to TLS connection now */ | ||||
|       const char *str; | ||||
| @@ -943,17 +953,12 @@ static CURLcode imap_parse_url_path(struct connectdata *conn) | ||||
|   struct imap_conn *imapc = &conn->proto.imapc; | ||||
|   struct SessionHandle *data = conn->data; | ||||
|   const char *path = data->state.path; | ||||
|   int len; | ||||
|  | ||||
|   if(!*path) | ||||
|     path = "INBOX"; | ||||
|  | ||||
|   /* url decode the path and use this mailbox */ | ||||
|   imapc->mailbox = curl_easy_unescape(data, path, 0, &len); | ||||
|   if(!imapc->mailbox) | ||||
|     return CURLE_OUT_OF_MEMORY; | ||||
|  | ||||
|   return CURLE_OK; | ||||
|   return Curl_urldecode(data, path, 0, &imapc->mailbox, NULL, TRUE); | ||||
| } | ||||
|  | ||||
| /* call this when the DO phase has completed */ | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * | ||||
|  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan | ||||
|  * (Royal Institute of Technology, Stockholm, Sweden). | ||||
|  * Copyright (c) 2004 - 2011 Daniel Stenberg | ||||
|  * Copyright (c) 2004 - 2012 Daniel Stenberg | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
| @@ -313,10 +313,13 @@ krb5_auth(void *app_data, struct connectdata *conn) | ||||
|  | ||||
| static void krb5_end(void *app_data) | ||||
| { | ||||
|     OM_uint32 maj, min; | ||||
|     OM_uint32 min; | ||||
|     gss_ctx_id_t *context = app_data; | ||||
|     if(*context != GSS_C_NO_CONTEXT) { | ||||
|       maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); | ||||
| #ifdef DEBUGBUILD | ||||
|       OM_uint32 maj = | ||||
| #endif | ||||
|       gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); | ||||
|       DEBUGASSERT(maj == GSS_S_COMPLETE); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -130,6 +130,7 @@ const struct Curl_handler Curl_handler_ldap = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
| @@ -154,6 +155,7 @@ const struct Curl_handler Curl_handler_ldaps = { | ||||
|   ZERO_NULL,                            /* doing */ | ||||
|   ZERO_NULL,                            /* proto_getsock */ | ||||
|   ZERO_NULL,                            /* doing_getsock */ | ||||
|   ZERO_NULL,                            /* domore_getsock */ | ||||
|   ZERO_NULL,                            /* perform_getsock */ | ||||
|   ZERO_NULL,                            /* disconnect */ | ||||
|   ZERO_NULL,                            /* readwrite */ | ||||
|   | ||||
| @@ -9,6 +9,8 @@ | ||||
| 	curl_easy_init, | ||||
| 	curl_easy_pause, | ||||
| 	curl_easy_perform, | ||||
| 	curl_easy_recv, | ||||
| 	curl_easy_send, | ||||
| 	curl_easy_setopt, | ||||
| 	curl_escape, | ||||
| 	curl_unescape, | ||||
| @@ -38,6 +40,8 @@ | ||||
| 	curl_multi_perform, | ||||
| 	curl_multi_cleanup, | ||||
| 	curl_multi_info_read, | ||||
| 	curl_multi_setopt, | ||||
| 	curl_multi_timeout, | ||||
| 	curl_free, | ||||
| 	curl_version_info, | ||||
| 	curl_share_init, | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user