Compare commits
	
		
			471 Commits
		
	
	
		
			curl-7_15_
			...
			curl-7_16_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 719bec2606 | ||
|   | b1db9dbb16 | ||
|   | 609044aea2 | ||
|   | ba481718a4 | ||
|   | 1be60dde7f | ||
|   | e92e811a61 | ||
|   | 5aa0db8681 | ||
|   | d5691211dd | ||
|   | a93695a70e | ||
|   | ce935a2697 | ||
|   | 812ce0d93f | ||
|   | bbae5b49f9 | ||
|   | 772a985dc3 | ||
|   | 8a7514de8a | ||
|   | 32ad212ac9 | ||
|   | 8a8d5c784c | ||
|   | 125830ab4b | ||
|   | 5b75b423e6 | ||
|   | 012d7e2878 | ||
|   | cd3029f36f | ||
|   | 6adaac7e18 | ||
|   | cde5e35d9b | ||
|   | ee17fba72e | ||
|   | 6296b89319 | ||
|   | 5450db9151 | ||
|   | b4700f026b | ||
|   | d771fa7c48 | ||
|   | b2c378267b | ||
|   | 384c8f3560 | ||
|   | f44ef427a2 | ||
|   | c54a4301ee | ||
|   | 36a3514225 | ||
|   | e1edd41e1b | ||
|   | 13e60c55a1 | ||
|   | 9b8b1a68f0 | ||
|   | 4ec9316155 | ||
|   | ef769500d4 | ||
|   | 23692574a2 | ||
|   | 5f6fd682a5 | ||
|   | db24518a30 | ||
|   | 90933ac660 | ||
|   | 087579a6f4 | ||
|   | de59cde155 | ||
|   | 3cd95eacdf | ||
|   | deb81b2ad4 | ||
|   | 4e717cdb30 | ||
|   | 33acd6f041 | ||
|   | 7575e6afc4 | ||
|   | 316a9f6480 | ||
|   | c6de584cad | ||
|   | d997ff6aa8 | ||
|   | b9ccecf86e | ||
|   | bd5d21aaf2 | ||
|   | 19e07771d1 | ||
|   | ef267ab449 | ||
|   | 4f6ed683e8 | ||
|   | c818e7064f | ||
|   | ead6ab2ef7 | ||
|   | 5c3dc49f44 | ||
|   | 83884180ac | ||
|   | 4cac96c33a | ||
|   | 5df4be1165 | ||
|   | 96445f1b7d | ||
|   | 4bdd7596d3 | ||
|   | 18aae32015 | ||
|   | a8996b9e52 | ||
|   | 94095c61d8 | ||
|   | 1cddd744ad | ||
|   | 786738dd00 | ||
|   | 5b8d5fdf2f | ||
|   | 694f31ca37 | ||
|   | 9c1ad0f9f7 | ||
|   | 71c6335293 | ||
|   | 8c38ea4ebc | ||
|   | 44d84ac164 | ||
|   | 930f9bd534 | ||
|   | b61fbbde46 | ||
|   | ec956b0334 | ||
|   | 44ffe0dc79 | ||
|   | e3a61fba52 | ||
|   | 65794f60ec | ||
|   | 7a710b4970 | ||
|   | 0bb20cc611 | ||
|   | 433c0c895e | ||
|   | 67e8d22958 | ||
|   | 10d1fc0e73 | ||
|   | 2260c8aa11 | ||
|   | 97eb62aff8 | ||
|   | 1855fc35f2 | ||
|   | dc3ed35313 | ||
|   | 6b868df554 | ||
|   | 5ccbbe40c2 | ||
|   | 86f93a53d6 | ||
|   | f53347631e | ||
|   | efe3cb6e1a | ||
|   | 32ac4edeed | ||
|   | 4c04c09138 | ||
|   | 47ea80baee | ||
|   | 95c3fa836b | ||
|   | ab60a12465 | ||
|   | 2d38e51867 | ||
|   | a5dda669e3 | ||
|   | 3c4f3a680a | ||
|   | b61c06384a | ||
|   | e7742bfb7c | ||
|   | 22307ae0ee | ||
|   | e150150d9f | ||
|   | 943f0733bb | ||
|   | 8274447dd9 | ||
|   | 083a84e5d0 | ||
|   | d5eb386d00 | ||
|   | 1ce7b48057 | ||
|   | cbcdd337aa | ||
|   | c144adf77c | ||
|   | d390039873 | ||
|   | 7d0c58a285 | ||
|   | 9263001b21 | ||
|   | 66ee6d07f8 | ||
|   | a40dcca794 | ||
|   | 15e3dfe1d3 | ||
|   | a1de9367ec | ||
|   | eceb37bde2 | ||
|   | 56fcf85ab6 | ||
|   | 77db81d661 | ||
|   | 2ad7fcbc2f | ||
|   | 2c62dfd124 | ||
|   | ef66497a0d | ||
|   | 1128029599 | ||
|   | befc30bc55 | ||
|   | ca5846cde9 | ||
|   | 8547ab1663 | ||
|   | 9c0e6ac365 | ||
|   | 552b963e6d | ||
|   | e2b48366d3 | ||
|   | 5e0d9aea32 | ||
|   | ae13c93b7d | ||
|   | b9f8a4a477 | ||
|   | 68e9f75708 | ||
|   | d569693f24 | ||
|   | 15d8bb2105 | ||
|   | b2ca777a08 | ||
|   | ba01198e6c | ||
|   | 6ebd5e1761 | ||
|   | 2723eda1e4 | ||
|   | 1fa3a5cce9 | ||
|   | fe8aee6b08 | ||
|   | 0639e2a6e2 | ||
|   | f1d707705e | ||
|   | 296a7db960 | ||
|   | 4c0936e72f | ||
|   | 0992e391ba | ||
|   | b22aaeef6a | ||
|   | 8090ee0e5d | ||
|   | f7d31bb3e3 | ||
|   | 9cd928674f | ||
|   | 3ea8a4d220 | ||
|   | b0d3ba76a0 | ||
|   | ab798fe5ba | ||
|   | e7d90e08b9 | ||
|   | c2404f77e9 | ||
|   | ec4a16f2e0 | ||
|   | ca5de26f50 | ||
|   | 71920d61e6 | ||
|   | 5de75eee56 | ||
|   | 2d5fc39d35 | ||
|   | c001ed53fa | ||
|   | 39e01e9349 | ||
|   | 9e54d4c7d2 | ||
|   | 56bf97ffc9 | ||
|   | 7d3e719a2c | ||
|   | e55d4fd5c1 | ||
|   | 5ee231415f | ||
|   | c866771cd2 | ||
|   | 4a24219a1a | ||
|   | 733a184ce0 | ||
|   | eee09e79e8 | ||
|   | 6df85adf3e | ||
|   | 3ee6036551 | ||
|   | fb65080548 | ||
|   | 3a5f21b0d1 | ||
|   | 13a5598dc3 | ||
|   | 5a6c89661a | ||
|   | 7c5745720a | ||
|   | 00ae13f966 | ||
|   | 29dc39fce1 | ||
|   | 5c184cfc0d | ||
|   | 055022a55f | ||
|   | c30e908034 | ||
|   | 8d24c0212e | ||
|   | 8240cea628 | ||
|   | f2a33eb372 | ||
|   | e134a40208 | ||
|   | 690888cfc1 | ||
|   | fb8d9b6645 | ||
|   | f7ddb39ee1 | ||
|   | 145084b699 | ||
|   | f1ba12607a | ||
|   | bb87b65f08 | ||
|   | b0f6e7cee4 | ||
|   | ed72d4e104 | ||
|   | 8ec1bfe897 | ||
|   | 1dec17562f | ||
|   | 9cc3795f1a | ||
|   | be1306a6c2 | ||
|   | e9160a31e0 | ||
|   | 0a670c578f | ||
|   | e3c15fc4b9 | ||
|   | dc7c915553 | ||
|   | b7eeb6e67f | ||
|   | 7e4193b538 | ||
|   | a932803eac | ||
|   | 52560142bf | ||
|   | 874a4ef8c7 | ||
|   | 0bb3ac7c31 | ||
|   | 1e9f5845ab | ||
|   | c41dfc2501 | ||
|   | 30ac7eced1 | ||
|   | 466d093a92 | ||
|   | 1e9be353c2 | ||
|   | 4f4277d9c7 | ||
|   | 6728bda5c5 | ||
|   | dc9f154823 | ||
|   | d7168a82e2 | ||
|   | c9c8ee3796 | ||
|   | c7aae10300 | ||
|   | 909941405f | ||
|   | 4031eb1d91 | ||
|   | 59cf6fd4f0 | ||
|   | 6de9732a88 | ||
|   | 1f7f500922 | ||
|   | 4b1462ec65 | ||
|   | 6ed47f0aad | ||
|   | 2d8c7ba9fc | ||
|   | 3b342d18bc | ||
|   | f24ad3800c | ||
|   | e2ff369eba | ||
|   | 9691a78f6b | ||
|   | 7ff6b6fafd | ||
|   | 7c621cfbdf | ||
|   | 5acadc9cd7 | ||
|   | 2ff609dd43 | ||
|   | da48a6ba87 | ||
|   | cd6c58216a | ||
|   | bdbd0cf27a | ||
|   | d792937686 | ||
|   | bac66ec26b | ||
|   | 77516822f6 | ||
|   | 37d8c67530 | ||
|   | cfdcae4bc7 | ||
|   | 74a6921bc4 | ||
|   | 490cccba3c | ||
|   | 839441e236 | ||
|   | ba9ea943e2 | ||
|   | 455087faae | ||
|   | 31def9e217 | ||
|   | ee3514ccdc | ||
|   | cf606d7da0 | ||
|   | eb26a581f9 | ||
|   | b04cbebf86 | ||
|   | 4272af801f | ||
|   | 0b633027cb | ||
|   | 93943ef949 | ||
|   | b184b87714 | ||
|   | a11473f85d | ||
|   | 1eedad27a2 | ||
|   | ac02d379ba | ||
|   | a4ebf5b507 | ||
|   | c410769588 | ||
|   | 997a987943 | ||
|   | 6201dc083a | ||
|   | b33f47804d | ||
|   | 7ba5e098a3 | ||
|   | 824b78021c | ||
|   | 31657c85e5 | ||
|   | 7010e5ea84 | ||
|   | 2cba6b246d | ||
|   | 52cc2a7a0c | ||
|   | c012e2b408 | ||
|   | 646a6b604f | ||
|   | cca00a6378 | ||
|   | 10b7fc7e51 | ||
|   | 43e4544d51 | ||
|   | 21aa8f0b45 | ||
|   | b708fa51ad | ||
|   | 8709f6c4b3 | ||
|   | 2ac560e58b | ||
|   | 8f8ba9486d | ||
|   | f55924b3e0 | ||
|   | 7240acdebc | ||
|   | b9b06b00bf | ||
|   | 51f258d103 | ||
|   | 4c75f1c7b7 | ||
|   | ed7bff1fec | ||
|   | 01a79be2c9 | ||
|   | d211fcd34f | ||
|   | 159834171e | ||
|   | 8a38c72c48 | ||
|   | fbcdc192d5 | ||
|   | ee642859ef | ||
|   | 9f579f12fc | ||
|   | 825a526789 | ||
|   | ae8a01ead6 | ||
|   | 9dde0b54a3 | ||
|   | f1343b2f55 | ||
|   | 962b7985e6 | ||
|   | 5a1c64d316 | ||
|   | 01b2cf82ec | ||
|   | c033c4c71c | ||
|   | aa791ee5cf | ||
|   | 305671e2ab | ||
|   | d654736834 | ||
|   | 2c81bfead5 | ||
|   | 77b3bc239d | ||
|   | c10d15aa0f | ||
|   | a88deadd6f | ||
|   | e6ea8f1199 | ||
|   | 4d4151f6c1 | ||
|   | 518becfe2e | ||
|   | 6f6b93da02 | ||
|   | 45b1843dc9 | ||
|   | cb86a302d8 | ||
|   | d15ed439ae | ||
|   | b765e1f3b7 | ||
|   | 2527b53019 | ||
|   | 78a47826b2 | ||
|   | ecfaa4f869 | ||
|   | f36adcdb73 | ||
|   | 13616f8f96 | ||
|   | ab486d1e27 | ||
|   | 9111909c1d | ||
|   | 4a1a1a75fb | ||
|   | e4d6ade4b3 | ||
|   | c82e880f5b | ||
|   | f2aa3b21e0 | ||
|   | 385db0e97d | ||
|   | 4e58da5222 | ||
|   | 1c6ebb0782 | ||
|   | 7e8b84c3e7 | ||
|   | 132067b081 | ||
|   | 8c36fc8f31 | ||
|   | 93858efe73 | ||
|   | ba7f27a3f6 | ||
|   | 2f70fb7015 | ||
|   | 655ec6bf8e | ||
|   | c4ad533300 | ||
|   | 5cdbd0cf4a | ||
|   | a55c70d4ae | ||
|   | 02938a010d | ||
|   | e40641bf7c | ||
|   | 27c0b43897 | ||
|   | d46de5ab8b | ||
|   | 73ebb0edde | ||
|   | 684245d6ce | ||
|   | d157c29269 | ||
|   | 4d2e81661b | ||
|   | 483a586d55 | ||
|   | 4ac54f8c2c | ||
|   | 840aacf7dd | ||
|   | ab4256d53a | ||
|   | 46c5e562bf | ||
|   | 42f5a90d09 | ||
|   | ef82da93fb | ||
|   | 06d05b18b2 | ||
|   | 431c4bd6e3 | ||
|   | f72c4e82fd | ||
|   | 9c83a20a27 | ||
|   | 773bec5ae5 | ||
|   | f3c508f6e8 | ||
|   | 2aa4710745 | ||
|   | 3b0a920fad | ||
|   | daef1cf34d | ||
|   | bd8d4637a3 | ||
|   | d2cefc140a | ||
|   | ccfce89423 | ||
|   | 700cd5805c | ||
|   | 498aad8587 | ||
|   | 73f407b7ae | ||
|   | 4be7dcba48 | ||
|   | f0694c582e | ||
|   | f90f0c98d9 | ||
|   | 95aecc5dbb | ||
|   | f975fd03a1 | ||
|   | 8272874704 | ||
|   | 86f4cead16 | ||
|   | 88a1a10e6f | ||
|   | 624e657210 | ||
|   | 2278e8f1ba | ||
|   | 58176d1484 | ||
|   | 10489879f7 | ||
|   | fe22872d14 | ||
|   | 4d95d23d99 | ||
|   | c6fc5a1a26 | ||
|   | 012d75442a | ||
|   | dcc7900e7c | ||
|   | 34f5e8ad0e | ||
|   | c2fee9894a | ||
|   | abd983e851 | ||
|   | 28611704d9 | ||
|   | 305dddeab0 | ||
|   | ee8112b42f | ||
|   | ca319f63ad | ||
|   | a09a8164db | ||
|   | e5cf6a20a7 | ||
|   | af5e6e7e6d | ||
|   | 70f2b5e877 | ||
|   | 8ef454dcbe | ||
|   | 551a041283 | ||
|   | 03288943af | ||
|   | 725f734bae | ||
|   | 0f32460656 | ||
|   | 25180cc850 | ||
|   | 2a0e41cab9 | ||
|   | 05edd48ad0 | ||
|   | 266ab95557 | ||
|   | 0a4bba565c | ||
|   | 2ddb9d57aa | ||
|   | 4f012ad703 | ||
|   | a1cd180082 | ||
|   | bc2f0c7dcb | ||
|   | c6ae0ebcbf | ||
|   | c6ec576cbb | ||
|   | 55329b56cb | ||
|   | 7e43d06b60 | ||
|   | 89f54f3739 | ||
|   | 01fa02d0b5 | ||
|   | 8bed45340a | ||
|   | 55138753c6 | ||
|   | 43369b8096 | ||
|   | bec1977137 | ||
|   | 4c08eb4b11 | ||
|   | 0163730437 | ||
|   | 39745ac38e | ||
|   | cacf8bbb58 | ||
|   | a1c6d5861a | ||
|   | 589c4596d8 | ||
|   | 7a6d7fca42 | ||
|   | 5305c9f1e8 | ||
|   | b1022ea4c1 | ||
|   | 380a74a4ed | ||
|   | ff709848a6 | ||
|   | 279dd6d878 | ||
|   | 2e0ad842d0 | ||
|   | a3949c7786 | ||
|   | 2320606262 | ||
|   | b01286d280 | ||
|   | 64f72c22b9 | ||
|   | 856114d05c | ||
|   | 98b8c4b0c9 | ||
|   | 01f5f0be5a | ||
|   | eb6d404753 | ||
|   | c508ab1aef | ||
|   | 0793dc922c | ||
|   | 00a41ab296 | ||
|   | 37f4877e56 | ||
|   | a6fc45c02f | ||
|   | 25411e01db | ||
|   | a8ac6f1dc1 | ||
|   | dfe1884c25 | ||
|   | 3e5dcc8bcd | ||
|   | ff81900784 | ||
|   | 4cb30a3057 | ||
|   | 72f80b88f7 | ||
|   | 3008d8133c | ||
|   | 4524618bf2 | ||
|   | 55d22ba10c | ||
|   | 76cf020750 | ||
|   | f13ac35edf | ||
|   | 59582a9d9d | ||
|   | 6246bbc656 | ||
|   | 1b028b419b | ||
|   | 4c6c768422 | 
							
								
								
									
										404
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										404
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -6,6 +6,398 @@ | ||||
|  | ||||
|                                   Changelog | ||||
|  | ||||
| Version 7.16.0 (30 October 2006) | ||||
|  | ||||
| Daniel (25 October 2006) | ||||
| - Fixed CURLOPT_FAILONERROR to return CURLE_HTTP_RETURNED_ERROR even for the | ||||
|   case when 401 or 407 are returned, *IF* no auth credentials have been given. | ||||
|   The CURLOPT_FAILONERROR option is not possible to make fool-proof for 401 | ||||
|   and 407 cases when auth credentials is given, but we've now covered this | ||||
|   somewhat more. | ||||
|  | ||||
|   You might get some amounts of headers transferred before this situation is | ||||
|   detected, like for when a "100-continue" is received as a response to a | ||||
|   POST/PUT and a 401 or 407 is received immediately afterwards. | ||||
|  | ||||
|   Added test 281 to verify this change. | ||||
|  | ||||
| Daniel (23 October 2006) | ||||
| - Ravi Pratap provided a major update with pipelining fixes. We also no longer | ||||
|   re-use connections (for pipelining) before the name resolving is done. | ||||
|  | ||||
| Daniel (21 October 2006) | ||||
| - Nir Soffer made the tests/libtest/Makefile.am use a proper variable for all | ||||
|   the single test applications' link and dependences, so that you easier can | ||||
|   override those from the command line when using make. | ||||
|  | ||||
| - Armel Asselin separated CA cert verification problems from problems with | ||||
|   reading the (local) CA cert file to let users easier pinpoint the actual | ||||
|   problem. CURLE_SSL_CACERT_BADFILE (77) is the new libcurl error code. | ||||
|  | ||||
| Daniel (18 October 2006) | ||||
| - Removed the "protocol-guessing" for URLs with host names starting with FTPS | ||||
|   or TELNET since they are practically non-existant. This leaves us with only | ||||
|   three different prefixes that would assume the protocol is anything but | ||||
|   HTTP, and they are host names starting with "ftp.", "dict." or "ldap.". | ||||
|  | ||||
| Daniel (17 October 2006) | ||||
| - Bug report #1579171 pointed out code flaws detected with "prefast", and they | ||||
|   were 1 - a too small memory clear with memset() in the threaded resolver and | ||||
|   2 - a range of potentially bad uses of the ctype family of is*() functions | ||||
|   such as isdigit(), isalnum(), isprint() and more. The latter made me switch | ||||
|   to using our own set of these functions/macros using uppercase letters, and | ||||
|   with some extra set of crazy typecasts to avoid mistakingly passing in | ||||
|   negative numbers to the underlying is*() functions. | ||||
|  | ||||
| - With Jeff Pohlmeyer's help, I fixed the expire timer when using | ||||
|   curl_multi_socket() during name resolves with c-ares and the LOW_SPEED | ||||
|   options now work fine with curl_multi_socket() as well. | ||||
|  | ||||
| Daniel (16 October 2006) | ||||
| - Added a check in configure that simply tries to run a program (not when | ||||
|   cross-compiling) in order to detect problems with run-time libraries that | ||||
|   otherwise would occur when the sizeof tests for curl_off_t would run and | ||||
|   thus be much more confusing to users. The check of course should run after | ||||
|   all lib-checks are done and before any other test is used that would run an | ||||
|   executable built for testing-purposes. | ||||
|  | ||||
| Dan F (13 October 2006) | ||||
| - The tagging of application/x-www-form-urlencoded POST body data sent | ||||
|   to the CURLOPT_DEBUGFUNCTION callback has been fixed (it was erroneously | ||||
|   included as part of the header).  A message was also added to the | ||||
|   command line tool to show when data is being sent, enabled when | ||||
|   --verbose is used. | ||||
|  | ||||
| Daniel (12 October 2006) | ||||
| - Starting now, adding an easy handle to a multi stack that was already added | ||||
|   to a multi stack will cause CURLM_BAD_EASY_HANDLE to get returned. | ||||
|  | ||||
| - Jeff Pohlmeyer has been working with the hiperfifo.c example source code, | ||||
|   and while doing so it became apparent that the current timeout system for | ||||
|   the socket API really was a bit awkward since it become quite some work to | ||||
|   be sure we have the correct timeout set. | ||||
|  | ||||
|   Jeff then provided the new CURLMOPT_TIMERFUNCTION that is yet another | ||||
|   callback the app can set to get to know when the general timeout time | ||||
|   changes and thus for an application like hiperfifo.c it makes everything a | ||||
|   lot easier and nicer. There's a CURLMOPT_TIMERDATA option too of course in | ||||
|   good old libcurl tradition. | ||||
|  | ||||
|   Jeff has also updated the hiperfifo.c example code to use this news. | ||||
|  | ||||
| Daniel (9 October 2006) | ||||
| - Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test | ||||
|   case 535 and it now runs fine. Again a problem with the pipelining code not | ||||
|   taking all possible (error) conditions into account. | ||||
|  | ||||
| Daniel (6 October 2006) | ||||
| - Bogdan Nicula's hanging test case (posted Wed, 04 Oct 2006) was converted to | ||||
|   test case 533 and the test now runs fine. | ||||
|  | ||||
| Daniel (4 October 2006) | ||||
| - Dmitriy Sergeyev provided an example source code that crashed CVS libcurl | ||||
|   but that worked nicely in 7.15.5. I converted it into test case 532 and | ||||
|   fixed the problem. | ||||
|  | ||||
| Daniel (29 September 2006) | ||||
| - Removed a few other no-longer present options from the header file. | ||||
|  | ||||
| - Support for FTP third party transfers was removed. Here's why: | ||||
|  | ||||
|   o The recent multi interface changes broke it and the design of the 3rd party | ||||
|     transfers made it very hard to fix the problems | ||||
|   o It was still blocking and thus nasty for the multi interface | ||||
|   o It was a lot of extra code for a very rarely used feature | ||||
|   o It didn't use the same code as for "plain" FTP transfers, so it didn't work | ||||
|     fine for IPv6 and it didn't properly re-use connections and more | ||||
|   o There's nobody around who's willing to work on and improve the existing | ||||
|     code | ||||
|  | ||||
|   This does not mean that third party transfers are banned forever, only that | ||||
|   they need to be done better if they are to be re-added in the future. | ||||
|  | ||||
|   The CURLOPT_SOURCE_* options are removed from the lib and so are the --3p* | ||||
|   options from the command line tool. For this reason, I also bumped the | ||||
|   version info for the lib. | ||||
|  | ||||
| Daniel (28 September 2006) | ||||
| - Reported in #1561470 (http://curl.haxx.se/bug/view.cgi?id=1561470), libcurl | ||||
|   would crash if a bad function sequence was used when shutting down after | ||||
|   using the multi interface (i.e using easy_cleanup after multi_cleanup) so | ||||
|   precautions have been added to make sure it doesn't any more - test case 529 | ||||
|   was added to verify. | ||||
|  | ||||
| Daniel (27 September 2006) | ||||
| - The URL in the cookie jar file is now changed since it was giving a 404. | ||||
|   Reported by Timothy Stone. The new URL will take the visitor to a curl web | ||||
|   site mirror with the document. | ||||
|  | ||||
| Daniel (24 September 2006) | ||||
| - Bernard Leak fixed configure --with-gssapi-libs. | ||||
|  | ||||
| - Cory Nelson made libcurl use the WSAPoll() function if built for Windows | ||||
|   Vista (_WIN32_WINNT >= 0x0600) | ||||
|  | ||||
| Daniel (23 September 2006) | ||||
| - Mike Protts added --ftp-ssl-control to make curl use FTP-SSL, but only | ||||
|   encrypt the control connection and use the data connection "plain". | ||||
|  | ||||
| - Dmitriy Sergeyev provided a patch that made the SOCKS[45] code work better | ||||
|   as it now will read the full data sent from servers. The SOCKS-related code | ||||
|   was also moved to the new lib/socks.c source file. | ||||
|  | ||||
| Daniel (21 September 2006) | ||||
| - Added test case 531 in an attempt to repeat bug report #1561470 | ||||
|   (http://curl.haxx.se/bug/view.cgi?id=1561470) that is said to crash when an | ||||
|   FTP upload fails with the multi interface. It did not, but I made a failed | ||||
|   upload still assume the control connection to be fine. | ||||
|  | ||||
| Daniel (20 September 2006) | ||||
| - Armel Asselin fixed problems when you gave a proxy URL with user name and | ||||
|   empty password or no password at all. Test case 278 and 279 were added to | ||||
|   verify. | ||||
|  | ||||
| Daniel (12 September 2006) | ||||
| - Added docs/examples/10-at-a-time.c by Michael Wallner | ||||
|  | ||||
| - Added docs/examples/hiperfifo.c by Jeff Pohlmeyer | ||||
|  | ||||
| Daniel (11 September 2006) | ||||
| - Fixed my breakage from earlier today so that doing curl_easy_cleanup() on a | ||||
|   handle that is part of a multi handle first removes the handle from the | ||||
|   stack. | ||||
|  | ||||
| - Added CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid to disable SSL | ||||
|   session-ID re-use on demand since there obviously are broken servers out | ||||
|   there that misbehave with session-IDs used. | ||||
|  | ||||
| - Jeff Pohlmeyer presented a *multi_socket()-using program that exposed a | ||||
|   problem with it (SIGSEGV-style). It clearly showed that the existing | ||||
|   socket-state and state-difference function wasn't good enough so I rewrote | ||||
|   it and could then re-run Jeff's program without any crash. The previous | ||||
|   version clearly could miss to tell the application when a handle changed | ||||
|   from using one socket to using another. | ||||
|  | ||||
|   While I was at it (as I could use this as a means to track this problem | ||||
|   down), I've now added a 'magic' number to the easy handle struct that is | ||||
|   inited at curl_easy_init() time and cleared at curl_easy_cleanup() time that | ||||
|   we can use internally to detect that an easy handle seems to be fine, or at | ||||
|   least not closed or freed (freeing in debug builds fill the area with 0x13 | ||||
|   bytes but in normal builds we can of course not assume any particular data | ||||
|   in the freed areas). | ||||
|  | ||||
| Daniel (9 September 2006) | ||||
| - Michele Bini fixed how the hostname is put in NTLM packages. As servers | ||||
|   don't expect fully qualified names we need to cut them off at the first dot. | ||||
|  | ||||
| - Peter Sylvester cleaned up and fixed the getsockname() uses in ftp.c. Some | ||||
|   of them can be completetly removed though... | ||||
|  | ||||
| Daniel (6 September 2006) | ||||
| - Ravi Pratap and I have implemented HTTP Pipelining support. Enable it for a | ||||
|   multi handle using CURLMOPT_PIPELINING and all HTTP connections done on that | ||||
|   handle will be attempted to get pipelined instead of done in parallell as | ||||
|   they are performed otherwise. | ||||
|  | ||||
|   As a side-effect from this work, connections are now shared between all easy | ||||
|   handles within a multi handle, so if you use N easy handles for transfers, | ||||
|   each of them can pick up and re-use a connection that was previously used by | ||||
|   any of the handles, be it the same or one of the others. | ||||
|  | ||||
|   This separation of the tight relationship between connections and easy | ||||
|   handles is most noticable when you close easy handles that have been used in | ||||
|   a multi handle and check amount of used memory or watch the debug output, as | ||||
|   there are times when libcurl will keep the easy handle around for a while | ||||
|   longer to be able to close it properly. Like for sending QUIT to close down | ||||
|   an FTP connection. | ||||
|  | ||||
|   This is a major change. | ||||
|    | ||||
| Daniel (4 September 2006) | ||||
| - Dmitry Rechkin (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a | ||||
|   patch that while not fixing things very nicely, it does make the SOCKS5 | ||||
|   proxy connection slightly better as it now acknowledges the timeout for | ||||
|   connection and it no longer segfaults in the case when SOCKS requires | ||||
|   authentication and you did not specify username:password. | ||||
|  | ||||
| Daniel (31 August 2006) | ||||
| - Dmitriy Sergeyev found and fixed a multi interface flaw when using asynch | ||||
|   name resolves. It could get stuck in the wrong state. | ||||
|  | ||||
| Gisle (29 August 2006) | ||||
| - Added support for other MS-DOS compilers (desides djgpp). All MS-DOS | ||||
|   compiler now uses the same config.dos file (renamed to config.h by | ||||
|   make). libcurl now builds fine using Watcom and Metaware's High-C | ||||
|   using the Watt-32 tcp/ip-stack. | ||||
|  | ||||
| Daniel (29 August 2006) | ||||
| - David McCreedy added CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA to | ||||
|   allow applications to set their own socket options. | ||||
|  | ||||
| Daniel (25 August 2006) | ||||
| - Armel Asselin reported that the 'running_handles' counter wasn't updated | ||||
|   properly if you removed a "live" handle from a multi handle with | ||||
|   curl_multi_remove_handle(). | ||||
|  | ||||
| Daniel (22 August 2006) | ||||
| - David McCreedy fixed a remaining mistake from the August 19 TYPE change. | ||||
|  | ||||
| - Peter Sylvester pointed out a flaw in the AllowServerConnect() in the FTP | ||||
|   code when doing pure ipv6 EPRT connections. | ||||
|  | ||||
| Daniel (19 August 2006) | ||||
| - Based on a patch by Armel Asselin, the FTP code no longer re-issues the TYPE | ||||
|   command on subsequent requests on a re-used connection unless it has to. | ||||
|  | ||||
| - Armel Asselin fixed a crash in the FTP code when using SINGLECWD mode and | ||||
|   files in the root directory. | ||||
|  | ||||
| - Andrew Biggs pointed out a "Expect: 100-continue" flaw where libcurl didn't | ||||
|   send the whole request at once, even though the Expect: header was disabled | ||||
|   by the application. An effect of this change is also that small (< 1024 | ||||
|   bytes) POSTs are now always sent without Expect: header since we deem it | ||||
|   more costly to bother about that than the risk that we send the data in | ||||
|   vain. | ||||
|  | ||||
| Daniel (9 August 2006) | ||||
| - Armel Asselin made the CURLOPT_PREQUOTE option work fine even when | ||||
|   CURLOPT_NOBODY is set true. PREQUOTE is then run roughly at the same place | ||||
|   in the command sequence as it would have run if there would've been a | ||||
|   transfer. | ||||
|  | ||||
| Daniel (8 August 2006) | ||||
| - Fixed a flaw in the "Expect: 100-continue" treatment. If you did two POSTs | ||||
|   on a persistent connection and allowed the first to use that header, you | ||||
|   could not disable it for the second request. | ||||
|  | ||||
| Daniel (7 August 2006) | ||||
| - Domenico Andreolfound a quick build error which happened because | ||||
|   src/config.h.in was not a proper duplcate of lib/config.h.in which it | ||||
|   should've been and this was due to the maketgz script not doing the cp | ||||
|   properly. | ||||
|  | ||||
| Version 7.15.5 (7 August 2006) | ||||
|  | ||||
| Daniel (2 August 2006) | ||||
| - Mark Lentczner fixed how libcurl was not properly doing chunked encoding | ||||
|   if the header "Transfer-Encoding: chunked" was set by the application. | ||||
|   http://curl.haxx.se/bug/view.cgi?id=1531838 | ||||
|  | ||||
| Daniel (1 August 2006) | ||||
| - Maciej Karpiuk fixed a crash that would occur if we passed Curl_strerror() | ||||
|   an unknown error number on glibc systems. | ||||
|   http://curl.haxx.se/bug/view.cgi?id=1532289 | ||||
|  | ||||
| Daniel (31 July 2006) | ||||
| - *ALERT* curl_multi_socket() and curl_multi_socket_all() got modified | ||||
|   prototypes: they both now provide the number of running handles back to the | ||||
|   calling function. It makes the functions resemble the good old | ||||
|   curl_multi_perform() more and provides a nice way to know when the multi | ||||
|   handle goes empty. | ||||
|  | ||||
|   ALERT2: don't use the curl_multi_socket*() functionality in anything | ||||
|   production-like until I say it's somewhat settled, as I suspect there might | ||||
|   be some further API changes before I'm done... | ||||
|  | ||||
| Daniel (28 July 2006) | ||||
| - Yves Lejeune fixed so that replacing Content-Type: when doing multipart | ||||
|   formposts work exactly the way you want it (and the way you'd assume it | ||||
|   works). | ||||
|  | ||||
| Daniel (27 July 2006) | ||||
| - David McCreedy added --ftp-ssl-reqd which makes curl *require* SSL for both | ||||
|   control and data connection, as the existing --ftp-ssl option only requests | ||||
|   it. | ||||
|  | ||||
| - [Hiper-related work] Added a function called curl_multi_assign() that will | ||||
|   set a private pointer added to the internal libcurl hash table for the | ||||
|   particular socket passed in to this function: | ||||
|  | ||||
|   CURLMcode curl_multi_assign(CURLM *multi_handle, | ||||
|                               curl_socket_t sockfd, | ||||
|                               void *sockp); | ||||
|  | ||||
|   'sockp' being a custom pointer set by the application to be associated with | ||||
|   this socket. The socket has to be already existing and in-use by libcurl, | ||||
|   like having already called the callback telling about its existance. | ||||
|  | ||||
|   The set hashp pointer will then be passed on to the callback in upcoming | ||||
|   calls when this same socket is used (in the brand new 'socketp' argument). | ||||
|  | ||||
| Daniel (26 July 2006) | ||||
| - Dan Nelson added the CURLOPT_FTP_ALTERNATIVE_TO_USER libcurl option and curl | ||||
|   tool option named --ftp-alternative-to-user. It provides a mean to send a | ||||
|   particular command if the normal USER/PASS approach fails. | ||||
|  | ||||
| - Michael Jerris added magic that builds lib/curllib.vcproj automatically for | ||||
|   newer MSVC. | ||||
|  | ||||
| Daniel (25 July 2006) | ||||
| - Georg Horn made the transfer timeout error message include more details. | ||||
|  | ||||
| Daniel (20 July 2006) | ||||
| - David McCreedy fixed a build error when building libcurl with HTTP disabled, | ||||
|   problem added with the curl_formget() patch. | ||||
|  | ||||
| Daniel (17 July 2006) | ||||
| - Jari Sundell did some excellent research and bug tracking, figured out that | ||||
|   we did wrong and patched it: When nodes were removed from the splay tree, | ||||
|   and we didn't properly remove it from the splay tree when an easy handle was | ||||
|   removed from a multi stack and thus we could wrongly leave a node in the | ||||
|   splay tree pointing to (bad) memory. | ||||
|  | ||||
| Daniel (14 July 2006) | ||||
| - David McCreedy fixed a flaw where the CRLF counter wasn't properly cleared | ||||
|   for FTP ASCII transfers. | ||||
|  | ||||
| Daniel (8 July 2006) | ||||
| - Ates Goral pointed out that libcurl's cookie parser did case insensitive | ||||
|   string comparisons on the path which is incorrect and provided a patch that | ||||
|   fixes this. I edited test case 8 to include details that test for this. | ||||
|  | ||||
| - Ingmar Runge provided a source snippet that caused a crash. The reason for | ||||
|   the crash was that libcurl internally was a bit confused about who owned the | ||||
|   DNS cache at all times so if you created an easy handle that uses a shared | ||||
|   DNS cache and added that to a multi handle it would crash. Now we keep more | ||||
|   careful internal track of exactly what kind of DNS cache each easy handle | ||||
|   uses: None, Private (allocated for and used only by this single handle), | ||||
|   Shared (points to a cache held by a shared object), Global (points to the | ||||
|   global cache) or Multi (points to the cache within the multi handle that is | ||||
|   automatically shared between all easy handles that are added with private | ||||
|   caches). | ||||
|  | ||||
| Daniel (4 July 2006) | ||||
| - Toshiyuki Maezawa fixed a problem where you couldn't override the | ||||
|   Proxy-Connection: header when using a proxy and not doing CONNECT. | ||||
|  | ||||
| Daniel (24 June 2006) | ||||
| - Michael Wallner added curl_formget(), which allows an application to extract | ||||
|   (serialise) a previously built formpost (as with curl_formadd()). | ||||
|  | ||||
| Daniel (23 June 2006) | ||||
| - Arve Knudsen found a flaw in curl_multi_fdset() for systems where | ||||
|   curl_socket_t is unsigned (like Windows) that could cause it to wrongly | ||||
|   return a max fd of -1. | ||||
|  | ||||
| Daniel (20 June 2006) | ||||
| - Peter Silva introduced CURLOPT_MAX_SEND_SPEED_LARGE and | ||||
|   CURLOPT_MAX_RECV_SPEED_LARGE that limit tha maximum rate libcurl is allowed | ||||
|   to send or receive data. This kind of adds the the command line tool's | ||||
|   option --limit-rate to the library. | ||||
|  | ||||
|   The rate limiting logic in the curl app is now removed and is instead | ||||
|   provided by libcurl itself. Transfer rate limiting will now also work for -d | ||||
|   and -F, which it didn't before. | ||||
|  | ||||
| Daniel (19 June 2006) | ||||
| - Made -K on a file that couldn't be read cause a warning to be displayed. | ||||
|  | ||||
| Daniel (13 June 2006) | ||||
| - Dan Fandrich implemented --enable-hidden-symbols configure option to enable | ||||
|   -fvisibility=hidden on gcc >= 4.0.  This reduces the size of the libcurl | ||||
|   binary and speeds up dynamic linking by hiding all the internal symbols from | ||||
|   the symbol table. | ||||
|  | ||||
| Version 7.15.4 (12 June 2006) | ||||
|  | ||||
| Daniel (8 June 2006) | ||||
| @@ -148,11 +540,11 @@ Daniel (4 May 2006) | ||||
|   already did this. | ||||
|  | ||||
| Daniel (2 May 2006) | ||||
| - Added a --checkfor option to curl-config to allow users to easier  | ||||
|   write for example shell scripts that test for the presence of a  | ||||
|   new-enough libcurl version. If --checkfor is given a version string  | ||||
|   newer than what is currently installed, curl-config will return a  | ||||
|   non-zero exit code and output a string about the unfulfilled  | ||||
| - Added a --checkfor option to curl-config to allow users to easier | ||||
|   write for example shell scripts that test for the presence of a | ||||
|   new-enough libcurl version. If --checkfor is given a version string | ||||
|   newer than what is currently installed, curl-config will return a | ||||
|   non-zero exit code and output a string about the unfulfilled | ||||
|   requirement. | ||||
|  | ||||
| Daniel (26 April 2006) | ||||
| @@ -208,7 +600,7 @@ Daniel (7 April 2006) | ||||
|  | ||||
|   CONV_FROM_NETWORK_FUNCTION | ||||
|   CONV_TO_NETWORK_FUNCTION | ||||
|   CONV_FROM_UTF8_FUNCTION  | ||||
|   CONV_FROM_UTF8_FUNCTION | ||||
|  | ||||
| Daniel (5 April 2006) | ||||
| - Michele Bini modified the NTLM code to work for his "weird IIS case" | ||||
|   | ||||
							
								
								
									
										2
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								README
									
									
									
									
									
								
							| @@ -7,7 +7,7 @@ | ||||
| README | ||||
|  | ||||
|   Curl is a command line tool for transferring data specified with URL | ||||
|   syntax. Find out how to use Curl by reading the curl.1 man page or the | ||||
|   syntax. Find out how to use curl by reading the curl.1 man page or the | ||||
|   MANUAL document. Find out how to install Curl by reading the INSTALL | ||||
|   document. | ||||
|  | ||||
|   | ||||
							
								
								
									
										114
									
								
								RELEASE-NOTES
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								RELEASE-NOTES
									
									
									
									
									
								
							| @@ -1,72 +1,80 @@ | ||||
| Curl and libcurl 7.15.4 | ||||
| Curl and libcurl 7.16.0 | ||||
|  | ||||
|  Public curl release number:               94 | ||||
|  Releases counted from the very beginning: 121 | ||||
|  Public curl release number:               96 | ||||
|  Releases counted from the very beginning: 123 | ||||
|  Available command line options:           112 | ||||
|  Available curl_easy_setopt() options:     132 | ||||
|  Number of public functions in libcurl:    49 | ||||
|  Amount of public web site mirrors:        33 | ||||
|  Number of known libcurl bindings:         32 | ||||
|  Number of contributors:                   492 | ||||
|  Available curl_easy_setopt() options:     133 | ||||
|  Number of public functions in libcurl:    54 | ||||
|  Amount of public web site mirrors:        37 | ||||
|  Number of known libcurl bindings:         35 | ||||
|  Number of contributors:                   515 | ||||
|  | ||||
| This release includes the following changes: | ||||
|  | ||||
|  o NTLM2 session response support | ||||
|  o CURLOPT_COOKIELIST set to "SESS" clears all session cookies | ||||
|  o CURLINFO_LASTSOCKET returned sockets are now checked more before returned | ||||
|  o curl-config got a --checkfor option to compare version numbers | ||||
|  o line end conversions for FTP ASCII transfers | ||||
|  o curl_multi_socket() API added (still mostly untested) | ||||
|  o conversion callback options for EBCDIC <=> ASCII conversions | ||||
|  o added CURLINFO_FTP_ENTRY_PATH | ||||
|  o less blocking for the multi interface during (Open)SSL connect negotiation | ||||
|   | ||||
|  o Added CURLE_SSL_CACERT_BADFILE | ||||
|  o Added CURLMOPT_TIMERFUNCTION and CURLMOPT_TIMERDATA | ||||
|  o (FTP) the CURLOPT_SOURCE_* options are removed and so are the --3p* command | ||||
|    line options | ||||
|  o curl_multi_socket() and family are suitable to start using | ||||
|  o uses WSAPoll() on Windows Vista | ||||
|  o (FTP) --ftp-ssl-control was added | ||||
|  o CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid added | ||||
|  o CURLMOPT_PIPELINING added for enabling HTTP pipelined transfers | ||||
|  o multi handles now have a shared connection cache | ||||
|  o Added support for other MS-DOS compilers (besides djgpp) | ||||
|  o CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA were added | ||||
|  o (FTP) libcurl avoids sending TYPE if the desired type was already set | ||||
|  o (FTP) CURLOPT_PREQUOTE works even when CURLOPT_NOBODY is set true | ||||
|  | ||||
| This release includes the following bugfixes: | ||||
|  | ||||
|  o builds fine on cygwin | ||||
|  o md5-sess with Digest authentication | ||||
|  o dict with letters such as space in a word | ||||
|  o dict with url-encoded words in the URL | ||||
|  o libcurl.m4 when default=yes but no libcurl was found | ||||
|  o numerous bugs fixed in the TFTP code | ||||
|  o possible memory leak when adding easy handles to multi stack | ||||
|  o TFTP works in a more portable fashion (== on more platforms) | ||||
|  o WSAGetLastError() is now used (better) on Windows | ||||
|  o GnuTLS non-block case that could cause data trashing | ||||
|  o deflate code survives lack of zlib header | ||||
|  o CURLOPT_INTERFACE works with hostname | ||||
|  o configure runs fine with ICC | ||||
|  o closed control connection with FTP when easy handle was removed from multi | ||||
|  o curl --trace crash when built with VS2005 | ||||
|  o SSL connect time-out | ||||
|  o improved NTLM functionality | ||||
|  o following redirects with more than one question mark in source URL | ||||
|  o fixed debug build crash with -d | ||||
|  o generates a fine AIX Toolbox RPM spec | ||||
|  o treat FTP AUTH failures properly | ||||
|  o TFTP transfers could trash data | ||||
|  o -d + -G combo crash | ||||
|  o (HTTP) CURLOPT_FAILONERROR (curl -f) covers a few more reponse cases | ||||
|  o curl_multi_socket() and the LOW_SPEED options | ||||
|  o curl_multi_socket() expire timer during c-ares name resolves | ||||
|  o curl_multi_add_handle on an already added handle now fails gracefully | ||||
|  o multi interface crash if bad function call order was used for cleanup | ||||
|  o put a new URL in saved cookie jar files | ||||
|  o configure --with-gssapi-libs | ||||
|  o SOCKS proxy connection fixes | ||||
|  o (FTP) a failed upload does not invalidate the control connection | ||||
|  o proxy URL with user name and empty password or no password at all now work | ||||
|  o fixed a socket state problem with *multi_socket() | ||||
|  o (HTTP) NTLM hostname fix | ||||
|  o getsockname usage fixes | ||||
|  o SOCKS5 proxy connects can now time-out | ||||
|  o SOCKS5 connects that require auth no longer segfaults when auth not given | ||||
|  o multi interface using asynch resolves could get stuck in wrong state | ||||
|  o the 'running_handles' counter wasn't always updated properly when | ||||
|    curl_multi_remove_handle() was used | ||||
|  o (FTP) EPRT transfers with IPv6 didn't work properly | ||||
|  o (FTP) SINGLECWD mode and using files in the root dir | ||||
|  o (HTTP) Expect: header disabling work better | ||||
|  o (HTTP) "Expect: 100-continue" disable on second POST on re-used connection | ||||
|  o src/config.h.in is fixed | ||||
|  o (HTTP) POST data logged to the debug callback function is now correctly | ||||
|    tagged as data, not header | ||||
|  | ||||
| Other curl-related news: | ||||
|  | ||||
|  o tclcurl 0.15.3 was released: | ||||
|    http://personal1.iddeo.es/andresgarci/tclcurl/english/ | ||||
|  o a Smalltalk binding: http://curl.haxx.se/libcurl/smalltalk/ | ||||
|  o pycurl-7.15.5 was released: http://pycurl.sf.net | ||||
|  | ||||
| New curl mirrors: | ||||
|  | ||||
|  o http://curl.webdesign-zdg.de/ in Frankfurt, Germany | ||||
|  o http://curl.de-mirror.de/ in Aachen, Germany | ||||
|  o http://curl.osmirror.nl/ in Amsterdam, the Netherlands | ||||
|  o http://curl.usphp.com/ in Florida, US | ||||
|  o http://curl.oslevel.de/ in Karlsruhe, Germany | ||||
|  o http://curl.geosdreams.info/ is a new Polish mirror | ||||
|  o http://curl.gfiles.org/ is a new Russian mirror | ||||
|  o http://curl.online-mirror.de/ is a new German mirror | ||||
|  o http://curl.blogvoid.com/ is a new Canadian mirror | ||||
|  o http://curl.internet.bs/ is a new United Kingdom mirror | ||||
|  o http://curl2.haxx.se/ is a new Swedish mirror | ||||
|  | ||||
| This release would not have looked like this without help, code, reports and | ||||
| advice from friends like these: | ||||
|  | ||||
|  Dan Fandrich, Ilja van Sprundel, David McCreedy, Tor Arntsen, Xavier Bouchoux, | ||||
|  David Byron, Michele Bini, Ates Goral, Katie Wang, Robson Braga Araujo, | ||||
|  Ale Vesely, Paul Querna, Gisle Vanem, Mark Eichin, Roland Blom, Andreas | ||||
|  Ntaflos, David Shaw, Michael Wallner, Olaf St<53>ben, Mikael Sennerholm, | ||||
|  Brian Dessent | ||||
|  Domenico Andreoli, Armel Asselin, Gisle Vanem, Yang Tse, Andrew Biggs, | ||||
|  Peter Sylvester, David McCreedy, Dmitriy Sergeyev, Dmitry Rechkin, | ||||
|  Jari Sundell, Ravi Pratap, Michele Bini, Jeff Pohlmeyer, Michael Wallner, | ||||
|  Mike Protts, Cory Nelson, Bernard Leak, Bogdan Nicula, Dan Fandrich, | ||||
|  Nir Soffer | ||||
|  | ||||
|         Thanks! (and sorry if I forgot to mention someone) | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| To get fixed in 7.15.4 (planned release: June 2006) | ||||
| To get fixed in 7.16.0 (planned release: October 2006) | ||||
| ====================== | ||||
|  | ||||
| 66 -  | ||||
| 67 - Jeff Pohlmeyer's crashing pipelining test case | ||||
|  | ||||
| 69 -  | ||||
|   | ||||
							
								
								
									
										854
									
								
								acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										854
									
								
								acinclude.m4
									
									
									
									
									
								
							| @@ -21,6 +21,7 @@ | ||||
| # $Id$ | ||||
| ########################################################################### | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_HEADER_WINDOWS | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for compilable and valid windows.h header  | ||||
| @@ -35,7 +36,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [ | ||||
| #endif | ||||
| #include <windows.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WINDOWS_H shall not be defined. | ||||
| #else | ||||
|         int dummy=2*WINVER; | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_windows_h="yes" | ||||
| @@ -43,12 +48,14 @@ AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [ | ||||
|       ac_cv_header_windows_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_windows_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1, | ||||
|       [Define to 1 if you have the windows.h header file.]) | ||||
|     AC_DEFINE_UNQUOTED(WIN32_LEAN_AND_MEAN, 1, | ||||
|       [Define to avoid automatic inclusion of winsock.h]) | ||||
|   fi | ||||
|   case "$ac_cv_header_windows_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1, | ||||
|         [Define to 1 if you have the windows.h header file.]) | ||||
|       AC_DEFINE_UNQUOTED(WIN32_LEAN_AND_MEAN, 1, | ||||
|         [Define to avoid automatic inclusion of winsock.h]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| @@ -68,7 +75,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [ | ||||
| #include <windows.h> | ||||
| #include <winsock.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WINSOCK_H shall not be defined. | ||||
| #else | ||||
|         int dummy=WSACleanup(); | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_winsock_h="yes" | ||||
| @@ -76,10 +87,12 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [ | ||||
|       ac_cv_header_winsock_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_winsock_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1, | ||||
|       [Define to 1 if you have the winsock.h header file.]) | ||||
|   fi | ||||
|   case "$ac_cv_header_winsock_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1, | ||||
|         [Define to 1 if you have the winsock.h header file.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| @@ -99,7 +112,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [ | ||||
| #include <windows.h> | ||||
| #include <winsock2.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WINSOCK2_H shall not be defined. | ||||
| #else | ||||
|         int dummy=2*IPPROTO_ESP; | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_winsock2_h="yes" | ||||
| @@ -107,10 +124,12 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [ | ||||
|       ac_cv_header_winsock2_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_winsock2_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1, | ||||
|       [Define to 1 if you have the winsock2.h header file.]) | ||||
|   fi | ||||
|   case "$ac_cv_header_winsock2_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1, | ||||
|         [Define to 1 if you have the winsock2.h header file.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| @@ -131,7 +150,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [ | ||||
| #include <winsock2.h> | ||||
| #include <ws2tcpip.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WS2TCPIP_H shall not be defined. | ||||
| #else | ||||
|         int dummy=2*IP_PKTINFO; | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_ws2tcpip_h="yes" | ||||
| @@ -139,9 +162,62 @@ AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [ | ||||
|       ac_cv_header_ws2tcpip_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_ws2tcpip_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1, | ||||
|       [Define to 1 if you have the ws2tcpip.h header file.]) | ||||
|   case "$ac_cv_header_ws2tcpip_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1, | ||||
|         [Define to 1 if you have the ws2tcpip.h header file.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_HEADER_MALLOC | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for compilable and valid malloc.h header, | ||||
| dnl and check if it is needed even with stdlib.h | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_HEADER_MALLOC], [ | ||||
|   AC_CACHE_CHECK([for malloc.h], [ac_cv_header_malloc_h], [ | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #include <malloc.h> | ||||
|       ],[ | ||||
|         void *p = malloc(10); | ||||
|         void *q = calloc(10,10); | ||||
|         free(p); | ||||
|         free(q); | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_malloc_h="yes" | ||||
|     ],[ | ||||
|       ac_cv_header_malloc_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "$ac_cv_header_malloc_h" = "yes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_MALLOC_H, 1, | ||||
|       [Define to 1 if you have the malloc.h header file.]) | ||||
|     # | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #include <stdlib.h> | ||||
|       ],[ | ||||
|         void *p = malloc(10); | ||||
|         void *q = calloc(10,10); | ||||
|         free(p); | ||||
|         free(q); | ||||
|       ]) | ||||
|     ],[ | ||||
|       curl_cv_need_header_malloc_h="no" | ||||
|     ],[ | ||||
|       curl_cv_need_header_malloc_h="yes" | ||||
|     ]) | ||||
|     # | ||||
|     case "$curl_cv_need_header_malloc_h" in | ||||
|       yes) | ||||
|         AC_DEFINE_UNQUOTED(NEED_MALLOC_H, 1, | ||||
|           [Define to 1 if you need the malloc.h header file even with stdlib.h]) | ||||
|         ;; | ||||
|     esac | ||||
|   fi | ||||
| ]) | ||||
|  | ||||
| @@ -194,12 +270,15 @@ AC_DEFUN([CURL_CHECK_TYPE_SOCKLEN_T], [ | ||||
|         done | ||||
|       done | ||||
|     ]) | ||||
|     if test "$curl_cv_socklen_t_equiv" = "unknown"; then | ||||
|       AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) | ||||
|     else | ||||
|       AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, | ||||
|         [type to use in place of socklen_t if not defined]) | ||||
|     fi | ||||
|     case "$curl_cv_socklen_t_equiv" in | ||||
|       unknown) | ||||
|         AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) | ||||
|         ;; | ||||
|       *) | ||||
|         AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, | ||||
|           [type to use in place of socklen_t if not defined]) | ||||
|         ;; | ||||
|     esac | ||||
|   ],[ | ||||
| #undef inline | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| @@ -232,9 +311,9 @@ dnl and check the types of five of its arguments. | ||||
| dnl If the function succeeds HAVE_GETNAMEINFO will be | ||||
| dnl defined, defining the types of the arguments in | ||||
| dnl GETNAMEINFO_TYPE_ARG1, GETNAMEINFO_TYPE_ARG2, | ||||
| dnl GETNAMEINFO_TYPE_ARG46 and GETNAMEINFO_TYPE_ARG7. | ||||
| dnl This function is experimental and its results shall | ||||
| dnl not be trusted while this notice is in place ------ | ||||
| dnl GETNAMEINFO_TYPE_ARG46 and GETNAMEINFO_TYPE_ARG7, | ||||
| dnl and also defining the type qualifier of first  | ||||
| dnl argument in GETNAMEINFO_QUAL_ARG1. | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [ | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WS2TCPIP])dnl | ||||
| @@ -370,14 +449,50 @@ AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [ | ||||
|       set dummy `echo "$curl_cv_func_getnameinfo_args" | sed 's/\*/\*/g'` | ||||
|       IFS=$gni_prev_IFS | ||||
|       shift | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG1, $[1], | ||||
|         [Define to the type of arg 1 for getnameinfo.]) | ||||
|       # | ||||
|       gni_qual_type_arg1=$[1] | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG2, $[2], | ||||
|         [Define to the type of arg 2 for getnameinfo.]) | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG46, $[3], | ||||
|         [Define to the type of args 4 and 6 for getnameinfo.]) | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG7, $[4], | ||||
|         [Define to the type of arg 7 for getnameinfo.]) | ||||
|       # | ||||
|       prev_sh_opts=$- | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set -f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       case "$gni_qual_type_arg1" in | ||||
|         const*) | ||||
|           gni_qual_arg1=const | ||||
|           gni_type_arg1=`echo $gni_qual_type_arg1 | sed 's/^const //'` | ||||
|         ;; | ||||
|         *) | ||||
|           gni_qual_arg1= | ||||
|           gni_type_arg1=$gni_qual_type_arg1 | ||||
|         ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_QUAL_ARG1, $gni_qual_arg1, | ||||
|         [Define to the type qualifier of arg 1 for getnameinfo.]) | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG1, $gni_type_arg1, | ||||
|         [Define to the type of arg 1 for getnameinfo.]) | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set +f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(HAVE_GETNAMEINFO, 1, | ||||
|         [Define to 1 if you have the getnameinfo function.]) | ||||
|       ac_cv_func_getnameinfo="yes" | ||||
| @@ -386,6 +501,540 @@ AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [ | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl TYPE_SOCKADDR_STORAGE | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for struct sockaddr_storage. Most IPv6-enabled  | ||||
| dnl hosts have it, but AIX 4.3 is one known exception. | ||||
|  | ||||
| AC_DEFUN([TYPE_SOCKADDR_STORAGE], | ||||
| [ | ||||
|    AC_CHECK_TYPE([struct sockaddr_storage], | ||||
|         AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, | ||||
|                   [if struct sockaddr_storage is defined]), , | ||||
|    [ | ||||
| #undef inline | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETINET_IN_H | ||||
| #include <netinet/in.h> | ||||
| #endif | ||||
| #ifdef HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
| #endif | ||||
|    ]) | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_NI_WITHSCOPEID | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for working NI_WITHSCOPEID in getnameinfo() | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_NI_WITHSCOPEID], [ | ||||
|   AC_REQUIRE([CURL_CHECK_FUNC_GETNAMEINFO])dnl | ||||
|   AC_REQUIRE([TYPE_SOCKADDR_STORAGE])dnl | ||||
|   AC_CHECK_HEADERS(stdio.h sys/types.h sys/socket.h \ | ||||
|                    netdb.h netinet/in.h arpa/inet.h) | ||||
|   # | ||||
|   AC_CACHE_CHECK([for working NI_WITHSCOPEID],  | ||||
|     [ac_cv_working_ni_withscopeid], [ | ||||
|     AC_RUN_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #ifdef HAVE_STDIO_H | ||||
| #include <stdio.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETDB_H | ||||
| #include <netdb.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETINET_IN_H | ||||
| #include <netinet/in.h> | ||||
| #endif | ||||
| #ifdef HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
|       ],[ | ||||
| #if defined(NI_WITHSCOPEID) && defined(HAVE_GETNAMEINFO) | ||||
| #ifdef HAVE_STRUCT_SOCKADDR_STORAGE | ||||
|         struct sockaddr_storage sa; | ||||
| #else | ||||
|         unsigned char sa[256]; | ||||
| #endif | ||||
|         char hostbuf[NI_MAXHOST]; | ||||
|         int rc; | ||||
|         GETNAMEINFO_TYPE_ARG2 salen = (GETNAMEINFO_TYPE_ARG2)sizeof(sa); | ||||
|         GETNAMEINFO_TYPE_ARG46 hostlen = (GETNAMEINFO_TYPE_ARG46)sizeof(hostbuf); | ||||
|         GETNAMEINFO_TYPE_ARG7 flags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; | ||||
|         int fd = socket(AF_INET6, SOCK_STREAM, 0); | ||||
|         if(fd < 0) { | ||||
|           perror("socket()"); | ||||
|           return 1; /* Error creating socket */ | ||||
|         } | ||||
|         rc = getsockname(fd, (GETNAMEINFO_TYPE_ARG1)&sa, &salen); | ||||
|         if(rc) { | ||||
|           perror("getsockname()"); | ||||
|           return 2; /* Error retrieving socket name */ | ||||
|         } | ||||
|         rc = getnameinfo((GETNAMEINFO_TYPE_ARG1)&sa, salen, hostbuf, hostlen, NULL, 0, flags); | ||||
|         if(rc) { | ||||
|           printf("rc = %s\n", gai_strerror(rc)); | ||||
|           return 3; /* Error translating socket address */ | ||||
|         } | ||||
|         return 0; /* Ok, NI_WITHSCOPEID works */ | ||||
| #else | ||||
|         return 4; /* Error, NI_WITHSCOPEID not defined or no getnameinfo() */ | ||||
| #endif | ||||
|       ]) # AC_LANG_PROGRAM | ||||
|     ],[ | ||||
|       # Exit code == 0. Program worked. | ||||
|       ac_cv_working_ni_withscopeid="yes" | ||||
|     ],[ | ||||
|       # Exit code != 0. Program failed. | ||||
|       ac_cv_working_ni_withscopeid="no" | ||||
|     ],[ | ||||
|       # Program is not run when cross-compiling. So we assume | ||||
|       # NI_WITHSCOPEID will work if we are able to compile it. | ||||
|       AC_COMPILE_IFELSE([ | ||||
|         AC_LANG_PROGRAM([ | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netdb.h> | ||||
|         ],[ | ||||
|           unsigned int dummy= NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; | ||||
|         ]) | ||||
|       ],[ | ||||
|         ac_cv_working_ni_withscopeid="yes" | ||||
|       ],[ | ||||
|         ac_cv_working_ni_withscopeid="no" | ||||
|       ]) # AC_COMPILE_IFELSE | ||||
|     ]) # AC_RUN_IFELSE | ||||
|   ]) # AC_CACHE_CHECK | ||||
|   case "$ac_cv_working_ni_withscopeid" in | ||||
|     yes) | ||||
|       AC_DEFINE(HAVE_NI_WITHSCOPEID, 1, | ||||
|         [Define to 1 if NI_WITHSCOPEID exists and works.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_FUNC_RECV | ||||
| dnl ------------------------------------------------- | ||||
| dnl Test if the socket recv() function is available,  | ||||
| dnl and check its return type and the types of its  | ||||
| dnl arguments. If the function succeeds HAVE_RECV  | ||||
| dnl will be defined, defining the types of the arguments  | ||||
| dnl in RECV_TYPE_ARG1, RECV_TYPE_ARG2, RECV_TYPE_ARG3  | ||||
| dnl and RECV_TYPE_ARG4, defining the type of the function | ||||
| dnl return value in RECV_TYPE_RETV. | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_FUNC_RECV], [ | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/socket.h) | ||||
|   # | ||||
|   AC_MSG_CHECKING([for recv]) | ||||
|   AC_TRY_LINK([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #endif | ||||
|     ],[ | ||||
|       recv(0, 0, 0, 0); | ||||
|     ],[  | ||||
|       AC_MSG_RESULT([yes]) | ||||
|       curl_cv_recv="yes" | ||||
|     ],[ | ||||
|       AC_MSG_RESULT([no]) | ||||
|       curl_cv_recv="no" | ||||
|   ]) | ||||
|   # | ||||
|   if test "$curl_cv_recv" = "yes"; then | ||||
|     AC_CACHE_CHECK([types of arguments and return type for recv], | ||||
|       [curl_cv_func_recv_args], [ | ||||
|       curl_cv_func_recv_args="unknown" | ||||
|       for recv_retv in 'int' 'ssize_t'; do | ||||
|         for recv_arg1 in 'int' 'ssize_t' 'SOCKET'; do | ||||
|           for recv_arg2 in 'char *' 'void *'; do | ||||
|             for recv_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do | ||||
|               for recv_arg4 in 'int' 'unsigned int'; do | ||||
|                 AC_COMPILE_IFELSE([ | ||||
|                   AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #define RECVCALLCONV PASCAL | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #define RECVCALLCONV | ||||
| #endif | ||||
|                     extern $recv_retv RECVCALLCONV recv($recv_arg1, $recv_arg2, $recv_arg3, $recv_arg4); | ||||
|                   ],[ | ||||
|                     $recv_arg1 s=0; | ||||
|                     $recv_arg2 buf=0; | ||||
|                     $recv_arg3 len=0; | ||||
|                     $recv_arg4 flags=0; | ||||
|                     $recv_retv res = recv(s, buf, len, flags); | ||||
|                   ]) | ||||
|                 ],[ | ||||
|                    curl_cv_func_recv_args="$recv_arg1,$recv_arg2,$recv_arg3,$recv_arg4,$recv_retv" | ||||
|                    break 5 | ||||
|                 ]) | ||||
|               done | ||||
|             done | ||||
|           done | ||||
|         done | ||||
|       done | ||||
|     ]) # AC_CACHE_CHECK | ||||
|     if test "$curl_cv_func_recv_args" = "unknown"; then | ||||
|       AC_MSG_ERROR([Cannot find proper types to use for recv args]) | ||||
|     else | ||||
|       recv_prev_IFS=$IFS; IFS=',' | ||||
|       set dummy `echo "$curl_cv_func_recv_args" | sed 's/\*/\*/g'` | ||||
|       IFS=$recv_prev_IFS | ||||
|       shift | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG1, $[1], | ||||
|         [Define to the type of arg 1 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG2, $[2], | ||||
|         [Define to the type of arg 2 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG3, $[3], | ||||
|         [Define to the type of arg 3 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG4, $[4], | ||||
|         [Define to the type of arg 4 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_RETV, $[5], | ||||
|         [Define to the function return type for recv.]) | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(HAVE_RECV, 1, | ||||
|         [Define to 1 if you have the recv function.]) | ||||
|       ac_cv_func_recv="yes" | ||||
|     fi | ||||
|   else | ||||
|     AC_MSG_ERROR([Unable to link function recv]) | ||||
|   fi | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_FUNC_SEND | ||||
| dnl ------------------------------------------------- | ||||
| dnl Test if the socket send() function is available,  | ||||
| dnl and check its return type and the types of its  | ||||
| dnl arguments. If the function succeeds HAVE_SEND  | ||||
| dnl will be defined, defining the types of the arguments  | ||||
| dnl in SEND_TYPE_ARG1, SEND_TYPE_ARG2, SEND_TYPE_ARG3  | ||||
| dnl and SEND_TYPE_ARG4, defining the type of the function | ||||
| dnl return value in SEND_TYPE_RETV, and also defining the  | ||||
| dnl type qualifier of second argument in SEND_QUAL_ARG2. | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_FUNC_SEND], [ | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/socket.h) | ||||
|   # | ||||
|   AC_MSG_CHECKING([for send]) | ||||
|   AC_TRY_LINK([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #endif | ||||
|     ],[ | ||||
|       send(0, 0, 0, 0); | ||||
|     ],[  | ||||
|       AC_MSG_RESULT([yes]) | ||||
|       curl_cv_send="yes" | ||||
|     ],[ | ||||
|       AC_MSG_RESULT([no]) | ||||
|       curl_cv_send="no" | ||||
|   ]) | ||||
|   # | ||||
|   if test "$curl_cv_send" = "yes"; then | ||||
|     AC_CACHE_CHECK([types of arguments and return type for send], | ||||
|       [curl_cv_func_send_args], [ | ||||
|       curl_cv_func_send_args="unknown" | ||||
|       for send_retv in 'int' 'ssize_t'; do | ||||
|         for send_arg1 in 'int' 'ssize_t' 'SOCKET'; do | ||||
|           for send_arg2 in 'char *' 'void *' 'const char *' 'const void *'; do | ||||
|             for send_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do | ||||
|               for send_arg4 in 'int' 'unsigned int'; do | ||||
|                 AC_COMPILE_IFELSE([ | ||||
|                   AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #define SENDCALLCONV PASCAL | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #define SENDCALLCONV | ||||
| #endif | ||||
|                     extern $send_retv SENDCALLCONV send($send_arg1, $send_arg2, $send_arg3, $send_arg4); | ||||
|                   ],[ | ||||
|                     $send_arg1 s=0; | ||||
|                     $send_arg3 len=0; | ||||
|                     $send_arg4 flags=0; | ||||
|                     $send_retv res = send(s, 0, len, flags); | ||||
|                   ]) | ||||
|                 ],[ | ||||
|                    curl_cv_func_send_args="$send_arg1,$send_arg2,$send_arg3,$send_arg4,$send_retv" | ||||
|                    break 5 | ||||
|                 ]) | ||||
|               done | ||||
|             done | ||||
|           done | ||||
|         done | ||||
|       done | ||||
|     ]) # AC_CACHE_CHECK | ||||
|     if test "$curl_cv_func_send_args" = "unknown"; then | ||||
|       AC_MSG_ERROR([Cannot find proper types to use for send args]) | ||||
|     else | ||||
|       send_prev_IFS=$IFS; IFS=',' | ||||
|       set dummy `echo "$curl_cv_func_send_args" | sed 's/\*/\*/g'` | ||||
|       IFS=$send_prev_IFS | ||||
|       shift | ||||
|       # | ||||
|       send_qual_type_arg2=$[2] | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG1, $[1], | ||||
|         [Define to the type of arg 1 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG3, $[3], | ||||
|         [Define to the type of arg 3 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG4, $[4], | ||||
|         [Define to the type of arg 4 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_RETV, $[5], | ||||
|         [Define to the function return type for send.]) | ||||
|       # | ||||
|       prev_sh_opts=$- | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set -f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       case "$send_qual_type_arg2" in | ||||
|         const*) | ||||
|           send_qual_arg2=const | ||||
|           send_type_arg2=`echo $send_qual_type_arg2 | sed 's/^const //'` | ||||
|         ;; | ||||
|         *) | ||||
|           send_qual_arg2= | ||||
|           send_type_arg2=$send_qual_type_arg2 | ||||
|         ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(SEND_QUAL_ARG2, $send_qual_arg2, | ||||
|         [Define to the type qualifier of arg 2 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG2, $send_type_arg2, | ||||
|         [Define to the type of arg 2 for send.]) | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set +f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(HAVE_SEND, 1, | ||||
|         [Define to 1 if you have the send function.]) | ||||
|       ac_cv_func_send="yes" | ||||
|     fi | ||||
|   else | ||||
|     AC_MSG_ERROR([Unable to link function send]) | ||||
|   fi | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_MSG_NOSIGNAL | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for MSG_NOSIGNAL | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [ | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/socket.h) | ||||
|   AC_CACHE_CHECK([for MSG_NOSIGNAL], [ac_cv_msg_nosignal], [ | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #endif | ||||
|       ],[ | ||||
|         int flag=MSG_NOSIGNAL; | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_msg_nosignal="yes" | ||||
|     ],[ | ||||
|       ac_cv_msg_nosignal="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   case "$ac_cv_msg_nosignal" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_MSG_NOSIGNAL, 1, | ||||
|         [Define to 1 if you have the MSG_NOSIGNAL flag.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_STRUCT_TIMEVAL | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for timeval struct | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [ | ||||
|   AC_REQUIRE([AC_HEADER_TIME])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/time.h time.h) | ||||
|   AC_CACHE_CHECK([for struct timeval], [ac_cv_struct_timeval], [ | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_TIME_H | ||||
| #include <sys/time.h> | ||||
| #ifdef TIME_WITH_SYS_TIME | ||||
| #include <time.h> | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_TIME_H | ||||
| #include <time.h> | ||||
| #endif | ||||
| #endif | ||||
|       ],[ | ||||
|         struct timeval ts; | ||||
|         ts.tv_sec  = 0; | ||||
|         ts.tv_usec = 0; | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_struct_timeval="yes" | ||||
|     ],[ | ||||
|       ac_cv_struct_timeval="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   case "$ac_cv_struct_timeval" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1, | ||||
|         [Define to 1 if you have the timeval struct.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_NONBLOCKING_SOCKET | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for how to set a socket to non-blocking state. There seems to exist | ||||
| @@ -528,43 +1177,6 @@ dnl end of non-blocking try-compile test | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl TYPE_SOCKADDR_STORAGE | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for struct sockaddr_storage. Most IPv6-enabled hosts have it, but | ||||
| dnl AIX 4.3 is one known exception. | ||||
| AC_DEFUN([TYPE_SOCKADDR_STORAGE], | ||||
| [ | ||||
|    AC_CHECK_TYPE([struct sockaddr_storage], | ||||
|         AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, | ||||
|                   [if struct sockaddr_storage is defined]), , | ||||
|    [ | ||||
| #undef inline | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETINET_IN_H | ||||
| #include <netinet/in.h> | ||||
| #endif | ||||
| #ifdef HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
| #endif | ||||
|    ]) | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl TYPE_IN_ADDR_T | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for in_addr_t: it is used to receive the return code of inet_addr() | ||||
| @@ -717,84 +1329,6 @@ if test "$ac_cv_working_getaddrinfo" = "yes"; then | ||||
| fi | ||||
| ]) | ||||
|  | ||||
| dnl ************************************************************ | ||||
| dnl check for working NI_WITHSCOPEID in getnameinfo() | ||||
| dnl | ||||
| AC_DEFUN([CURL_CHECK_NI_WITHSCOPEID],[ | ||||
|   AC_CACHE_CHECK(for working NI_WITHSCOPEID, ac_cv_working_ni_withscopeid,[ | ||||
|  | ||||
|  AC_RUN_IFELSE([[ | ||||
| #include <stdio.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netdb.h> | ||||
| int main() | ||||
| { | ||||
| #ifdef NI_WITHSCOPEID | ||||
|    struct sockaddr_storage ss; | ||||
|    int sslen = sizeof(ss); | ||||
|    int rc; | ||||
|    char hbuf[NI_MAXHOST]; | ||||
|    int fd = socket(AF_INET6, SOCK_STREAM, 0); | ||||
|    if(fd < 0) { | ||||
|      perror("socket()"); | ||||
|      return 1; /* couldn't create socket of either kind */ | ||||
|    } | ||||
|  | ||||
|    rc = getsockname(fd, (struct sockaddr *)&ss, &sslen); | ||||
|    if(rc) { | ||||
|      perror("getsockname()"); | ||||
|      return 2; | ||||
|    } | ||||
|  | ||||
|    rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), | ||||
|                      NULL, 0, | ||||
|                      NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID); | ||||
|  | ||||
|    if(rc) { | ||||
|      printf("rc = %s\n", gai_strerror(rc)); | ||||
|      return 3; | ||||
|    } | ||||
|  | ||||
|    return 0; /* everything works fine, use NI_WITHSCOPEID! */ | ||||
| #else | ||||
|    return 4; /* we don't seem to have the definition, don't use it */ | ||||
| #endif | ||||
| } | ||||
| ]], | ||||
| dnl program worked: | ||||
| [ ac_cv_working_ni_withscopeid="yes" ], | ||||
| dnl program failed: | ||||
| [ ac_cv_working_ni_withscopeid="no" ], | ||||
| dnl we cross-compile, check the headers using the preprocessor | ||||
| [ | ||||
|  | ||||
|  AC_EGREP_CPP(WORKS, | ||||
| [ | ||||
| #include <stdio.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netdb.h> | ||||
|  | ||||
| #ifdef NI_WITHSCOPEID | ||||
| WORKS | ||||
| #endif | ||||
| ], | ||||
|   ac_cv_working_ni_withscopeid="yes", | ||||
|   ac_cv_working_ni_withscopeid="no" ) | ||||
|  | ||||
|  ] | ||||
| ) dnl end of AC_RUN_IFELSE | ||||
|  | ||||
| ]) dnl end of AC_CACHE_CHECK | ||||
|  | ||||
| if test "$ac_cv_working_ni_withscopeid" = "yes"; then | ||||
|   AC_DEFINE(HAVE_NI_WITHSCOPEID, 1, | ||||
|             [Define if NI_WITHSCOPEID exists and works]) | ||||
| fi | ||||
|  | ||||
| ]) dnl end of AC_DEFUN | ||||
|  | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_LOCALTIME_R], | ||||
| [ | ||||
| @@ -1339,3 +1873,37 @@ else | ||||
|   AC_MSG_WARN([`missing' script is too old or missing]) | ||||
| fi | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl CURL_VERIFY_RUNTIMELIBS | ||||
| dnl ------------------------------------------------- | ||||
| dnl Verify that the shared libs found so far can be used when running | ||||
| dnl programs, since otherwise the situation will create odd configure errors | ||||
| dnl that are misleading people. | ||||
| dnl | ||||
| dnl Make sure this test is run BEFORE the first test in the script that | ||||
| dnl runs anything, which at the time of this writing is the AC_CHECK_SIZEOF | ||||
| dnl macro. It must also run AFTER all lib-checking macros are complete. | ||||
|  | ||||
| AC_DEFUN([CURL_VERIFY_RUNTIMELIBS], [ | ||||
|  | ||||
|   dnl this test is of course not sensible if we are cross-compiling! | ||||
|   if test "x$cross_compiling" != xyes; then | ||||
|  | ||||
|     dnl just run a program to verify that the libs checked for previous to this | ||||
|     dnl point also is available run-time! | ||||
|     AC_MSG_CHECKING([run-time libs availability]) | ||||
|     AC_TRY_RUN([ | ||||
| main() | ||||
| { | ||||
|   return 0; | ||||
| } | ||||
| ], | ||||
|     AC_MSG_RESULT([fine]), | ||||
|     AC_MSG_RESULT([failed]) | ||||
|     AC_MSG_ERROR([one or more libs available at link-time are not available run-time. Libs used at link-time: $LIBS]) | ||||
|     ) | ||||
|  | ||||
|     dnl if this test fails, configure has already stopped | ||||
|   fi | ||||
| ]) | ||||
|   | ||||
							
								
								
									
										52
									
								
								ares/CHANGES
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								ares/CHANGES
									
									
									
									
									
								
							| @@ -1,5 +1,55 @@ | ||||
|   Changelog for the c-ares project | ||||
|  | ||||
| * October 12 2006 | ||||
|  | ||||
| - Prevent ares_getsock() to overflow if more than 16 sockets are used. | ||||
|  | ||||
| * September 11 2006 | ||||
|  | ||||
| - Guilherme Balena Versiani: I noted a strange BUG in Win32 port | ||||
|   (ares_init.c/get_iphlpapi_dns_info() function): when I disable the network | ||||
|   by hand or disconnect the network cable in Windows 2000 or Windows XP, my | ||||
|   application gets 127.0.0.1 as the only name server. The problem comes from | ||||
|   'GetNetworkParams' function, that returns the empty string "" as the only | ||||
|   name server in that case. Moreover, the Windows implementation of | ||||
|   inet_addr() returns INADDR_LOOPBACK instead of INADDR_NONE. | ||||
|  | ||||
| * August 29 2006 | ||||
|  | ||||
| - Brad Spencer did | ||||
|  | ||||
|   o made ares_version.h use extern "C" for c++ compilers | ||||
|   o fixed compiler warnings in ares_getnameinfo.c | ||||
|   o fixed a buffer position init for TCP reads | ||||
|  | ||||
| * August 3 2006 | ||||
|  | ||||
| - Ravi Pratap fixed ares_getsock() to actually return the proper bitmap and | ||||
|   not always zero! | ||||
|  | ||||
| Version 1.3.1 (June 24, 2006) | ||||
|  | ||||
| * July 23, 2006 | ||||
|  | ||||
| - Gisle Vanem added getopt() to the ahost program. Currently accepts | ||||
|   only [-t {a|aaaa}] to specify address family in ares_gethostbyname(). | ||||
|  | ||||
| * June 19, 2006 | ||||
|  | ||||
| - (wahern) Removed "big endian" DNS section and RR data integer parser | ||||
|   macros from ares_dns.h, which break c-ares on my Sparc64. Bit-wise | ||||
|   operations in C operate on logical values. And in any event the octets are | ||||
|   already in big-endian (aka network) byte order so they're being reversed | ||||
|   (thus the source of the breakage). | ||||
|  | ||||
| * June 18, 2006 | ||||
|  | ||||
| - William Ahern handles EAGAIN/EWOULDBLOCK errors in most of the I/O calls | ||||
|   from area_process.c. | ||||
|  | ||||
|   TODO: Handle one last EAGAIN for a UDP socket send(2) in | ||||
|   ares__send_query(). | ||||
|  | ||||
| * May 10, 2006 | ||||
|  | ||||
| - Bram Matthys brought my attention to a libtool peculiarity where detecting | ||||
| @@ -49,7 +99,7 @@ | ||||
| - configure fix for detecting a member in the sockaddr_in6 struct which failed | ||||
|   on ipv6-enabled HP-UX 11.00 | ||||
|  | ||||
| Version 1.3.0 (August 29, 2004) | ||||
| Version 1.3.0 (August 29, 2005) | ||||
|  | ||||
| * August 21 | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ MSVCFILES = vc/adig/adig.dep vc/adig/adig.dsp vc/vc.dsw vc/ahost/ahost.dep \ | ||||
| # adig and ahost are just sample programs and thus not mentioned with the | ||||
| # regular sources and headers | ||||
| EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \ | ||||
|  $(MSVCFILES) AUTHORS | ||||
|  $(MSVCFILES) AUTHORS config-win32.h | ||||
|  | ||||
|  | ||||
| VER=-version-info 1:0:0 | ||||
|   | ||||
| @@ -13,6 +13,8 @@ CFLAGS  = -O2 -Wall -DWATT32 -Dselect=select_s -DHAVE_AF_INET6 \ | ||||
|           -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET -DHAVE_STRUCT_IN6_ADDR \ | ||||
|           -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \ | ||||
|           -DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 \ | ||||
|           -DHAVE_SYS_TIME_H -DHAVE_TIME_H \ | ||||
|           -DTIME_WITH_SYS_TIME -DHAVE_STRUCT_TIMEVAL \ | ||||
|           -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -I$(WATT32_ROOT)/inc | ||||
|  | ||||
| LDFLAGS = -s | ||||
|   | ||||
| @@ -8,11 +8,14 @@ ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c	\ | ||||
| ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c | ||||
|  | ||||
| HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h          \ | ||||
|            nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h | ||||
|            nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h      \ | ||||
|            setup_once.h  | ||||
|  | ||||
| MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \ | ||||
|  ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3                \ | ||||
|  ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3        \ | ||||
|  ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3                 \ | ||||
|  ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3      \ | ||||
|  ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 | ||||
|  ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3    \ | ||||
|  ares_getsock.3 | ||||
|  | ||||
|   | ||||
| @@ -276,7 +276,9 @@ config.h: Makefile.netware | ||||
| 	@echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_RECV 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_SEND 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@ | ||||
| @@ -297,15 +299,27 @@ config.h: Makefile.netware | ||||
| 	@echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_UNAME 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_UNISTD_H 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@ | ||||
| 	@echo $(DL)#define RECV_TYPE_ARG2 char *$(DL) >> $@ | ||||
| 	@echo $(DL)#define RECV_TYPE_ARG3 int$(DL) >> $@ | ||||
| 	@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ | ||||
| 	@echo $(DL)#define RECV_TYPE_RETV int$(DL) >> $@ | ||||
| 	@echo $(DL)#define RETSIGTYPE void$(DL) >> $@ | ||||
| 	@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ | ||||
| 	@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ | ||||
| 	@echo $(DL)#define SEND_TYPE_ARG2 char *$(DL) >> $@ | ||||
| 	@echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@ | ||||
| 	@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ | ||||
| 	@echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@ | ||||
| 	@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@ | ||||
| 	@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@ | ||||
| 	@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ | ||||
| 	@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ | ||||
| ifdef NW_WINSOCK | ||||
|   | ||||
| @@ -140,51 +140,58 @@ vclean realclean: clean | ||||
| # | ||||
| # Copyright "gcc -MM .." | ||||
| # | ||||
| $(OBJ_DIR)\ares_fds.obj: ares_fds.c setup.h ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_process.obj: ares_process.c setup.h nameser.h ares.h ares_dns.h \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_free_hostent.obj: ares_free_hostent.c setup.h ares.h ares_private.h \ | ||||
| $(OBJ_DIR)\ares_fds.obj: ares_fds.c setup.h setup_once.h ares.h ares_private.h \ | ||||
|   ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_query.obj: ares_query.c setup.h nameser.h ares.h ares_dns.h \ | ||||
| $(OBJ_DIR)\ares_process.obj: ares_process.c setup.h setup_once.h nameser.h     \ | ||||
|   ares.h ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_free_hostent.obj: ares_free_hostent.c setup.h setup_once.h     \ | ||||
|   ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_query.obj: ares_query.c setup.h setup_once.h nameser.h         \ | ||||
|   ares.h ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares__close_sockets.obj: ares__close_sockets.c setup.h setup_once.h \ | ||||
|   ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_free_string.obj: ares_free_string.c setup.h setup_once.h ares.h | ||||
| $(OBJ_DIR)\ares_search.obj: ares_search.c setup.h setup_once.h nameser.h       \ | ||||
|   ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares__get_hostent.obj: ares__get_hostent.c setup.h setup_once.h     \ | ||||
|   ares.h ares_private.h ares_ipv6.h inet_net_pton.h | ||||
| $(OBJ_DIR)\ares_gethostbyaddr.obj: ares_gethostbyaddr.c setup.h setup_once.h   \ | ||||
|   nameser.h ares.h ares_private.h ares_ipv6.h inet_net_pton.h | ||||
| $(OBJ_DIR)\ares_send.obj: ares_send.c setup.h setup_once.h nameser.h ares.h    \ | ||||
|   ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares__read_line.obj: ares__read_line.c setup.h setup_once.h ares.h  \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares__close_sockets.obj: ares__close_sockets.c setup.h ares.h \ | ||||
| $(OBJ_DIR)\ares_gethostbyname.obj: ares_gethostbyname.c setup.h setup_once.h   \ | ||||
|   nameser.h ares.h ares_private.h ares_ipv6.h inet_net_pton.h bitncmp.h | ||||
| $(OBJ_DIR)\ares_strerror.obj: ares_strerror.c setup.h setup_once.h ares.h | ||||
| $(OBJ_DIR)\ares_cancel.obj: ares_cancel.c setup.h setup_once.h ares.h          \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_free_string.obj: ares_free_string.c setup.h ares.h | ||||
| $(OBJ_DIR)\ares_search.obj: ares_search.c setup.h nameser.h ares.h ares_private.h \ | ||||
|   ares_ipv6.h | ||||
| $(OBJ_DIR)\ares__get_hostent.obj: ares__get_hostent.c setup.h ares.h ares_private.h \ | ||||
|   ares_ipv6.h inet_net_pton.h | ||||
| $(OBJ_DIR)\ares_gethostbyaddr.obj: ares_gethostbyaddr.c setup.h nameser.h ares.h \ | ||||
| $(OBJ_DIR)\ares_init.obj: ares_init.c setup.h setup_once.h nameser.h ares.h    \ | ||||
|   ares_private.h ares_ipv6.h inet_net_pton.h | ||||
| $(OBJ_DIR)\ares_send.obj: ares_send.c setup.h nameser.h ares.h ares_dns.h \ | ||||
| $(OBJ_DIR)\ares_timeout.obj: ares_timeout.c setup.h setup_once.h ares.h        \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares__read_line.obj: ares__read_line.c setup.h ares.h ares_private.h \ | ||||
| $(OBJ_DIR)\ares_destroy.obj: ares_destroy.c setup.h setup_once.h ares.h        \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_mkquery.obj: ares_mkquery.c setup.h setup_once.h nameser.h     \ | ||||
|   ares.h ares_dns.h | ||||
| $(OBJ_DIR)\ares_version.obj: ares_version.c setup.h setup_once.h ares_version.h | ||||
| $(OBJ_DIR)\ares_expand_name.obj: ares_expand_name.c setup.h setup_once.h       \ | ||||
|   nameser.h ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_parse_a_reply.obj: ares_parse_a_reply.c setup.h setup_once.h   \ | ||||
|   nameser.h ares.h ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\windows_port.obj: windows_port.c setup.h setup_once.h nameser.h     \ | ||||
|   ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_expand_string.obj: ares_expand_string.c setup.h setup_once.h   \ | ||||
|   nameser.h ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_parse_ptr_reply.obj: ares_parse_ptr_reply.c setup.h            \ | ||||
|   setup_once.h nameser.h ares.h ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_parse_aaaa_reply.obj: ares_parse_aaaa_reply.c setup.h          \ | ||||
|   setup_once.h nameser.h ares.h ares_dns.h inet_net_pton.h ares_private.h      \ | ||||
|   ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_gethostbyname.obj: ares_gethostbyname.c setup.h nameser.h ares.h \ | ||||
|   ares_private.h ares_ipv6.h inet_net_pton.h bitncmp.h | ||||
| $(OBJ_DIR)\ares_strerror.obj: ares_strerror.c setup.h ares.h | ||||
| $(OBJ_DIR)\ares_cancel.obj: ares_cancel.c setup.h ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_init.obj: ares_init.c setup.h nameser.h ares.h ares_private.h \ | ||||
| $(OBJ_DIR)\ares_getnameinfo.obj: ares_getnameinfo.c setup.h setup_once.h       \ | ||||
|   nameser.h ares.h ares_private.h ares_ipv6.h inet_ntop.h | ||||
| $(OBJ_DIR)\inet_net_pton.obj: inet_net_pton.c setup.h setup_once.h nameser.h   \ | ||||
|   ares_ipv6.h inet_net_pton.h | ||||
| $(OBJ_DIR)\ares_timeout.obj: ares_timeout.c setup.h ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_destroy.obj: ares_destroy.c setup.h ares.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_mkquery.obj: ares_mkquery.c setup.h nameser.h ares.h ares_dns.h | ||||
| $(OBJ_DIR)\ares_version.obj: ares_version.c setup.h ares_version.h | ||||
| $(OBJ_DIR)\ares_expand_name.obj: ares_expand_name.c setup.h nameser.h ares.h \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_parse_a_reply.obj: ares_parse_a_reply.c setup.h nameser.h ares.h \ | ||||
|   ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\windows_port.obj: windows_port.c setup.h nameser.h ares.h ares_private.h \ | ||||
|   ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_expand_string.obj: ares_expand_string.c setup.h nameser.h ares.h \ | ||||
|   ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_parse_ptr_reply.obj: ares_parse_ptr_reply.c setup.h nameser.h ares.h \ | ||||
|   ares_dns.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_parse_aaaa_reply.obj: ares_parse_aaaa_reply.c setup.h nameser.h ares.h \ | ||||
|   ares_dns.h inet_net_pton.h ares_private.h ares_ipv6.h | ||||
| $(OBJ_DIR)\ares_getnameinfo.obj: ares_getnameinfo.c setup.h nameser.h ares.h \ | ||||
|   ares_private.h ares_ipv6.h inet_ntop.h | ||||
| $(OBJ_DIR)\inet_net_pton.obj: inet_net_pton.c setup.h nameser.h ares_ipv6.h \ | ||||
|   inet_net_pton.h | ||||
| $(OBJ_DIR)\bitncmp.obj: bitncmp.c bitncmp.h | ||||
| $(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h nameser.h ares_ipv6.h inet_ntop.h | ||||
| $(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h setup_once.h nameser.h           \ | ||||
|   ares_ipv6.h inet_ntop.h | ||||
|   | ||||
| @@ -14,7 +14,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [ | ||||
| #endif | ||||
| #include <windows.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WINDOWS_H shall not be defined. | ||||
| #else | ||||
|         int dummy=2*WINVER; | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_windows_h="yes" | ||||
| @@ -22,12 +26,14 @@ AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [ | ||||
|       ac_cv_header_windows_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_windows_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1, | ||||
|       [Define to 1 if you have the windows.h header file.]) | ||||
|     AC_DEFINE_UNQUOTED(WIN32_LEAN_AND_MEAN, 1, | ||||
|       [Define to avoid automatic inclusion of winsock.h]) | ||||
|   fi | ||||
|   case "$ac_cv_header_windows_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1, | ||||
|         [Define to 1 if you have the windows.h header file.]) | ||||
|       AC_DEFINE_UNQUOTED(WIN32_LEAN_AND_MEAN, 1, | ||||
|         [Define to avoid automatic inclusion of winsock.h]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| @@ -47,7 +53,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [ | ||||
| #include <windows.h> | ||||
| #include <winsock.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WINSOCK_H shall not be defined. | ||||
| #else | ||||
|         int dummy=WSACleanup(); | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_winsock_h="yes" | ||||
| @@ -55,10 +65,12 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [ | ||||
|       ac_cv_header_winsock_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_winsock_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1, | ||||
|       [Define to 1 if you have the winsock.h header file.]) | ||||
|   fi | ||||
|   case "$ac_cv_header_winsock_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1, | ||||
|         [Define to 1 if you have the winsock.h header file.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| @@ -78,7 +90,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [ | ||||
| #include <windows.h> | ||||
| #include <winsock2.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WINSOCK2_H shall not be defined. | ||||
| #else | ||||
|         int dummy=2*IPPROTO_ESP; | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_winsock2_h="yes" | ||||
| @@ -86,10 +102,12 @@ AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [ | ||||
|       ac_cv_header_winsock2_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_winsock2_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1, | ||||
|       [Define to 1 if you have the winsock2.h header file.]) | ||||
|   fi | ||||
|   case "$ac_cv_header_winsock2_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1, | ||||
|         [Define to 1 if you have the winsock2.h header file.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| @@ -110,7 +128,11 @@ AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [ | ||||
| #include <winsock2.h> | ||||
| #include <ws2tcpip.h> | ||||
|       ],[ | ||||
| #ifdef __CYGWIN__ | ||||
|         HAVE_WS2TCPIP_H shall not be defined. | ||||
| #else | ||||
|         int dummy=2*IP_PKTINFO; | ||||
| #endif | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_ws2tcpip_h="yes" | ||||
| @@ -118,9 +140,62 @@ AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [ | ||||
|       ac_cv_header_ws2tcpip_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "x$ac_cv_header_ws2tcpip_h" = "xyes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1, | ||||
|       [Define to 1 if you have the ws2tcpip.h header file.]) | ||||
|   case "$ac_cv_header_ws2tcpip_h" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1, | ||||
|         [Define to 1 if you have the ws2tcpip.h header file.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_HEADER_MALLOC | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for compilable and valid malloc.h header, | ||||
| dnl and check if it is needed even with stdlib.h | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_HEADER_MALLOC], [ | ||||
|   AC_CACHE_CHECK([for malloc.h], [ac_cv_header_malloc_h], [ | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #include <malloc.h> | ||||
|       ],[ | ||||
|         void *p = malloc(10); | ||||
|         void *q = calloc(10,10); | ||||
|         free(p); | ||||
|         free(q); | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_header_malloc_h="yes" | ||||
|     ],[ | ||||
|       ac_cv_header_malloc_h="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   if test "$ac_cv_header_malloc_h" = "yes"; then | ||||
|     AC_DEFINE_UNQUOTED(HAVE_MALLOC_H, 1, | ||||
|       [Define to 1 if you have the malloc.h header file.]) | ||||
|     # | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #include <stdlib.h> | ||||
|       ],[ | ||||
|         void *p = malloc(10); | ||||
|         void *q = calloc(10,10); | ||||
|         free(p); | ||||
|         free(q); | ||||
|       ]) | ||||
|     ],[ | ||||
|       curl_cv_need_header_malloc_h="no" | ||||
|     ],[ | ||||
|       curl_cv_need_header_malloc_h="yes" | ||||
|     ]) | ||||
|     # | ||||
|     case "$curl_cv_need_header_malloc_h" in | ||||
|       yes) | ||||
|         AC_DEFINE_UNQUOTED(NEED_MALLOC_H, 1, | ||||
|           [Define to 1 if you need the malloc.h header file even with stdlib.h]) | ||||
|         ;; | ||||
|     esac | ||||
|   fi | ||||
| ]) | ||||
|  | ||||
| @@ -173,12 +248,15 @@ AC_DEFUN([CURL_CHECK_TYPE_SOCKLEN_T], [ | ||||
|         done | ||||
|       done | ||||
|     ]) | ||||
|     if test "$curl_cv_socklen_t_equiv" = "unknown"; then | ||||
|       AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) | ||||
|     else | ||||
|       AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, | ||||
|         [type to use in place of socklen_t if not defined]) | ||||
|     fi | ||||
|     case "$curl_cv_socklen_t_equiv" in | ||||
|       unknown) | ||||
|         AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) | ||||
|         ;; | ||||
|       *) | ||||
|         AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, | ||||
|           [type to use in place of socklen_t if not defined]) | ||||
|         ;; | ||||
|     esac | ||||
|   ],[ | ||||
| #undef inline | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| @@ -211,9 +289,9 @@ dnl and check the types of five of its arguments. | ||||
| dnl If the function succeeds HAVE_GETNAMEINFO will be | ||||
| dnl defined, defining the types of the arguments in | ||||
| dnl GETNAMEINFO_TYPE_ARG1, GETNAMEINFO_TYPE_ARG2, | ||||
| dnl GETNAMEINFO_TYPE_ARG46 and GETNAMEINFO_TYPE_ARG7. | ||||
| dnl This function is experimental and its results shall | ||||
| dnl not be trusted while this notice is in place ------ | ||||
| dnl GETNAMEINFO_TYPE_ARG46 and GETNAMEINFO_TYPE_ARG7, | ||||
| dnl and also defining the type qualifier of first  | ||||
| dnl argument in GETNAMEINFO_QUAL_ARG1. | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [ | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WS2TCPIP])dnl | ||||
| @@ -349,14 +427,50 @@ AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [ | ||||
|       set dummy `echo "$curl_cv_func_getnameinfo_args" | sed 's/\*/\*/g'` | ||||
|       IFS=$gni_prev_IFS | ||||
|       shift | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG1, $[1], | ||||
|         [Define to the type of arg 1 for getnameinfo.]) | ||||
|       # | ||||
|       gni_qual_type_arg1=$[1] | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG2, $[2], | ||||
|         [Define to the type of arg 2 for getnameinfo.]) | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG46, $[3], | ||||
|         [Define to the type of args 4 and 6 for getnameinfo.]) | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG7, $[4], | ||||
|         [Define to the type of arg 7 for getnameinfo.]) | ||||
|       # | ||||
|       prev_sh_opts=$- | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set -f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       case "$gni_qual_type_arg1" in | ||||
|         const*) | ||||
|           gni_qual_arg1=const | ||||
|           gni_type_arg1=`echo $gni_qual_type_arg1 | sed 's/^const //'` | ||||
|         ;; | ||||
|         *) | ||||
|           gni_qual_arg1= | ||||
|           gni_type_arg1=$gni_qual_type_arg1 | ||||
|         ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_QUAL_ARG1, $gni_qual_arg1, | ||||
|         [Define to the type qualifier of arg 1 for getnameinfo.]) | ||||
|       AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG1, $gni_type_arg1, | ||||
|         [Define to the type of arg 1 for getnameinfo.]) | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set +f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(HAVE_GETNAMEINFO, 1, | ||||
|         [Define to 1 if you have the getnameinfo function.]) | ||||
|       ac_cv_func_getnameinfo="yes" | ||||
| @@ -365,6 +479,540 @@ AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [ | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl TYPE_SOCKADDR_STORAGE | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for struct sockaddr_storage. Most IPv6-enabled  | ||||
| dnl hosts have it, but AIX 4.3 is one known exception. | ||||
|  | ||||
| AC_DEFUN([TYPE_SOCKADDR_STORAGE], | ||||
| [ | ||||
|    AC_CHECK_TYPE([struct sockaddr_storage], | ||||
|         AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, | ||||
|                   [if struct sockaddr_storage is defined]), , | ||||
|    [ | ||||
| #undef inline | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETINET_IN_H | ||||
| #include <netinet/in.h> | ||||
| #endif | ||||
| #ifdef HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
| #endif | ||||
|    ]) | ||||
| ]) | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_NI_WITHSCOPEID | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for working NI_WITHSCOPEID in getnameinfo() | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_NI_WITHSCOPEID], [ | ||||
|   AC_REQUIRE([CURL_CHECK_FUNC_GETNAMEINFO])dnl | ||||
|   AC_REQUIRE([TYPE_SOCKADDR_STORAGE])dnl | ||||
|   AC_CHECK_HEADERS(stdio.h sys/types.h sys/socket.h \ | ||||
|                    netdb.h netinet/in.h arpa/inet.h) | ||||
|   # | ||||
|   AC_CACHE_CHECK([for working NI_WITHSCOPEID],  | ||||
|     [ac_cv_working_ni_withscopeid], [ | ||||
|     AC_RUN_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #ifdef HAVE_STDIO_H | ||||
| #include <stdio.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETDB_H | ||||
| #include <netdb.h> | ||||
| #endif | ||||
| #ifdef HAVE_NETINET_IN_H | ||||
| #include <netinet/in.h> | ||||
| #endif | ||||
| #ifdef HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
|       ],[ | ||||
| #if defined(NI_WITHSCOPEID) && defined(HAVE_GETNAMEINFO) | ||||
| #ifdef HAVE_STRUCT_SOCKADDR_STORAGE | ||||
|         struct sockaddr_storage sa; | ||||
| #else | ||||
|         unsigned char sa[256]; | ||||
| #endif | ||||
|         char hostbuf[NI_MAXHOST]; | ||||
|         int rc; | ||||
|         GETNAMEINFO_TYPE_ARG2 salen = (GETNAMEINFO_TYPE_ARG2)sizeof(sa); | ||||
|         GETNAMEINFO_TYPE_ARG46 hostlen = (GETNAMEINFO_TYPE_ARG46)sizeof(hostbuf); | ||||
|         GETNAMEINFO_TYPE_ARG7 flags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; | ||||
|         int fd = socket(AF_INET6, SOCK_STREAM, 0); | ||||
|         if(fd < 0) { | ||||
|           perror("socket()"); | ||||
|           return 1; /* Error creating socket */ | ||||
|         } | ||||
|         rc = getsockname(fd, (GETNAMEINFO_TYPE_ARG1)&sa, &salen); | ||||
|         if(rc) { | ||||
|           perror("getsockname()"); | ||||
|           return 2; /* Error retrieving socket name */ | ||||
|         } | ||||
|         rc = getnameinfo((GETNAMEINFO_TYPE_ARG1)&sa, salen, hostbuf, hostlen, NULL, 0, flags); | ||||
|         if(rc) { | ||||
|           printf("rc = %s\n", gai_strerror(rc)); | ||||
|           return 3; /* Error translating socket address */ | ||||
|         } | ||||
|         return 0; /* Ok, NI_WITHSCOPEID works */ | ||||
| #else | ||||
|         return 4; /* Error, NI_WITHSCOPEID not defined or no getnameinfo() */ | ||||
| #endif | ||||
|       ]) # AC_LANG_PROGRAM | ||||
|     ],[ | ||||
|       # Exit code == 0. Program worked. | ||||
|       ac_cv_working_ni_withscopeid="yes" | ||||
|     ],[ | ||||
|       # Exit code != 0. Program failed. | ||||
|       ac_cv_working_ni_withscopeid="no" | ||||
|     ],[ | ||||
|       # Program is not run when cross-compiling. So we assume | ||||
|       # NI_WITHSCOPEID will work if we are able to compile it. | ||||
|       AC_COMPILE_IFELSE([ | ||||
|         AC_LANG_PROGRAM([ | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netdb.h> | ||||
|         ],[ | ||||
|           unsigned int dummy= NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; | ||||
|         ]) | ||||
|       ],[ | ||||
|         ac_cv_working_ni_withscopeid="yes" | ||||
|       ],[ | ||||
|         ac_cv_working_ni_withscopeid="no" | ||||
|       ]) # AC_COMPILE_IFELSE | ||||
|     ]) # AC_RUN_IFELSE | ||||
|   ]) # AC_CACHE_CHECK | ||||
|   case "$ac_cv_working_ni_withscopeid" in | ||||
|     yes) | ||||
|       AC_DEFINE(HAVE_NI_WITHSCOPEID, 1, | ||||
|         [Define to 1 if NI_WITHSCOPEID exists and works.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_FUNC_RECV | ||||
| dnl ------------------------------------------------- | ||||
| dnl Test if the socket recv() function is available,  | ||||
| dnl and check its return type and the types of its  | ||||
| dnl arguments. If the function succeeds HAVE_RECV  | ||||
| dnl will be defined, defining the types of the arguments  | ||||
| dnl in RECV_TYPE_ARG1, RECV_TYPE_ARG2, RECV_TYPE_ARG3  | ||||
| dnl and RECV_TYPE_ARG4, defining the type of the function | ||||
| dnl return value in RECV_TYPE_RETV. | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_FUNC_RECV], [ | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/socket.h) | ||||
|   # | ||||
|   AC_MSG_CHECKING([for recv]) | ||||
|   AC_TRY_LINK([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #endif | ||||
|     ],[ | ||||
|       recv(0, 0, 0, 0); | ||||
|     ],[  | ||||
|       AC_MSG_RESULT([yes]) | ||||
|       curl_cv_recv="yes" | ||||
|     ],[ | ||||
|       AC_MSG_RESULT([no]) | ||||
|       curl_cv_recv="no" | ||||
|   ]) | ||||
|   # | ||||
|   if test "$curl_cv_recv" = "yes"; then | ||||
|     AC_CACHE_CHECK([types of arguments and return type for recv], | ||||
|       [curl_cv_func_recv_args], [ | ||||
|       curl_cv_func_recv_args="unknown" | ||||
|       for recv_retv in 'int' 'ssize_t'; do | ||||
|         for recv_arg1 in 'int' 'ssize_t' 'SOCKET'; do | ||||
|           for recv_arg2 in 'char *' 'void *'; do | ||||
|             for recv_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do | ||||
|               for recv_arg4 in 'int' 'unsigned int'; do | ||||
|                 AC_COMPILE_IFELSE([ | ||||
|                   AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #define RECVCALLCONV PASCAL | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #define RECVCALLCONV | ||||
| #endif | ||||
|                     extern $recv_retv RECVCALLCONV recv($recv_arg1, $recv_arg2, $recv_arg3, $recv_arg4); | ||||
|                   ],[ | ||||
|                     $recv_arg1 s=0; | ||||
|                     $recv_arg2 buf=0; | ||||
|                     $recv_arg3 len=0; | ||||
|                     $recv_arg4 flags=0; | ||||
|                     $recv_retv res = recv(s, buf, len, flags); | ||||
|                   ]) | ||||
|                 ],[ | ||||
|                    curl_cv_func_recv_args="$recv_arg1,$recv_arg2,$recv_arg3,$recv_arg4,$recv_retv" | ||||
|                    break 5 | ||||
|                 ]) | ||||
|               done | ||||
|             done | ||||
|           done | ||||
|         done | ||||
|       done | ||||
|     ]) # AC_CACHE_CHECK | ||||
|     if test "$curl_cv_func_recv_args" = "unknown"; then | ||||
|       AC_MSG_ERROR([Cannot find proper types to use for recv args]) | ||||
|     else | ||||
|       recv_prev_IFS=$IFS; IFS=',' | ||||
|       set dummy `echo "$curl_cv_func_recv_args" | sed 's/\*/\*/g'` | ||||
|       IFS=$recv_prev_IFS | ||||
|       shift | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG1, $[1], | ||||
|         [Define to the type of arg 1 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG2, $[2], | ||||
|         [Define to the type of arg 2 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG3, $[3], | ||||
|         [Define to the type of arg 3 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_ARG4, $[4], | ||||
|         [Define to the type of arg 4 for recv.]) | ||||
|       AC_DEFINE_UNQUOTED(RECV_TYPE_RETV, $[5], | ||||
|         [Define to the function return type for recv.]) | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(HAVE_RECV, 1, | ||||
|         [Define to 1 if you have the recv function.]) | ||||
|       ac_cv_func_recv="yes" | ||||
|     fi | ||||
|   else | ||||
|     AC_MSG_ERROR([Unable to link function recv]) | ||||
|   fi | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_FUNC_SEND | ||||
| dnl ------------------------------------------------- | ||||
| dnl Test if the socket send() function is available,  | ||||
| dnl and check its return type and the types of its  | ||||
| dnl arguments. If the function succeeds HAVE_SEND  | ||||
| dnl will be defined, defining the types of the arguments  | ||||
| dnl in SEND_TYPE_ARG1, SEND_TYPE_ARG2, SEND_TYPE_ARG3  | ||||
| dnl and SEND_TYPE_ARG4, defining the type of the function | ||||
| dnl return value in SEND_TYPE_RETV, and also defining the  | ||||
| dnl type qualifier of second argument in SEND_QUAL_ARG2. | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_FUNC_SEND], [ | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/socket.h) | ||||
|   # | ||||
|   AC_MSG_CHECKING([for send]) | ||||
|   AC_TRY_LINK([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #endif | ||||
|     ],[ | ||||
|       send(0, 0, 0, 0); | ||||
|     ],[  | ||||
|       AC_MSG_RESULT([yes]) | ||||
|       curl_cv_send="yes" | ||||
|     ],[ | ||||
|       AC_MSG_RESULT([no]) | ||||
|       curl_cv_send="no" | ||||
|   ]) | ||||
|   # | ||||
|   if test "$curl_cv_send" = "yes"; then | ||||
|     AC_CACHE_CHECK([types of arguments and return type for send], | ||||
|       [curl_cv_func_send_args], [ | ||||
|       curl_cv_func_send_args="unknown" | ||||
|       for send_retv in 'int' 'ssize_t'; do | ||||
|         for send_arg1 in 'int' 'ssize_t' 'SOCKET'; do | ||||
|           for send_arg2 in 'char *' 'void *' 'const char *' 'const void *'; do | ||||
|             for send_arg3 in 'size_t' 'int' 'socklen_t' 'unsigned int'; do | ||||
|               for send_arg4 in 'int' 'unsigned int'; do | ||||
|                 AC_COMPILE_IFELSE([ | ||||
|                   AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #define SENDCALLCONV PASCAL | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #define SENDCALLCONV | ||||
| #endif | ||||
|                     extern $send_retv SENDCALLCONV send($send_arg1, $send_arg2, $send_arg3, $send_arg4); | ||||
|                   ],[ | ||||
|                     $send_arg1 s=0; | ||||
|                     $send_arg3 len=0; | ||||
|                     $send_arg4 flags=0; | ||||
|                     $send_retv res = send(s, 0, len, flags); | ||||
|                   ]) | ||||
|                 ],[ | ||||
|                    curl_cv_func_send_args="$send_arg1,$send_arg2,$send_arg3,$send_arg4,$send_retv" | ||||
|                    break 5 | ||||
|                 ]) | ||||
|               done | ||||
|             done | ||||
|           done | ||||
|         done | ||||
|       done | ||||
|     ]) # AC_CACHE_CHECK | ||||
|     if test "$curl_cv_func_send_args" = "unknown"; then | ||||
|       AC_MSG_ERROR([Cannot find proper types to use for send args]) | ||||
|     else | ||||
|       send_prev_IFS=$IFS; IFS=',' | ||||
|       set dummy `echo "$curl_cv_func_send_args" | sed 's/\*/\*/g'` | ||||
|       IFS=$send_prev_IFS | ||||
|       shift | ||||
|       # | ||||
|       send_qual_type_arg2=$[2] | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG1, $[1], | ||||
|         [Define to the type of arg 1 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG3, $[3], | ||||
|         [Define to the type of arg 3 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG4, $[4], | ||||
|         [Define to the type of arg 4 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_RETV, $[5], | ||||
|         [Define to the function return type for send.]) | ||||
|       # | ||||
|       prev_sh_opts=$- | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set -f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       case "$send_qual_type_arg2" in | ||||
|         const*) | ||||
|           send_qual_arg2=const | ||||
|           send_type_arg2=`echo $send_qual_type_arg2 | sed 's/^const //'` | ||||
|         ;; | ||||
|         *) | ||||
|           send_qual_arg2= | ||||
|           send_type_arg2=$send_qual_type_arg2 | ||||
|         ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(SEND_QUAL_ARG2, $send_qual_arg2, | ||||
|         [Define to the type qualifier of arg 2 for send.]) | ||||
|       AC_DEFINE_UNQUOTED(SEND_TYPE_ARG2, $send_type_arg2, | ||||
|         [Define to the type of arg 2 for send.]) | ||||
|       # | ||||
|       case $prev_sh_opts in | ||||
|         *f*) | ||||
|           ;; | ||||
|         *) | ||||
|           set +f | ||||
|           ;; | ||||
|       esac | ||||
|       # | ||||
|       AC_DEFINE_UNQUOTED(HAVE_SEND, 1, | ||||
|         [Define to 1 if you have the send function.]) | ||||
|       ac_cv_func_send="yes" | ||||
|     fi | ||||
|   else | ||||
|     AC_MSG_ERROR([Unable to link function send]) | ||||
|   fi | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_MSG_NOSIGNAL | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for MSG_NOSIGNAL | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [ | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/socket.h) | ||||
|   AC_CACHE_CHECK([for MSG_NOSIGNAL], [ac_cv_msg_nosignal], [ | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_SOCKET_H | ||||
| #include <sys/socket.h> | ||||
| #endif | ||||
| #endif | ||||
|       ],[ | ||||
|         int flag=MSG_NOSIGNAL; | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_msg_nosignal="yes" | ||||
|     ],[ | ||||
|       ac_cv_msg_nosignal="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   case "$ac_cv_msg_nosignal" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_MSG_NOSIGNAL, 1, | ||||
|         [Define to 1 if you have the MSG_NOSIGNAL flag.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_STRUCT_TIMEVAL | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for timeval struct | ||||
|  | ||||
| AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [ | ||||
|   AC_REQUIRE([AC_HEADER_TIME])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl | ||||
|   AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl | ||||
|   AC_CHECK_HEADERS(sys/types.h sys/time.h time.h) | ||||
|   AC_CACHE_CHECK([for struct timeval], [ac_cv_struct_timeval], [ | ||||
|     AC_COMPILE_IFELSE([ | ||||
|       AC_LANG_PROGRAM([ | ||||
| #undef inline  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <windows.h> | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #include <winsock2.h> | ||||
| #else | ||||
| #ifdef HAVE_WINSOCK_H | ||||
| #include <winsock.h> | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
| #ifdef HAVE_SYS_TYPES_H | ||||
| #include <sys/types.h> | ||||
| #endif | ||||
| #ifdef HAVE_SYS_TIME_H | ||||
| #include <sys/time.h> | ||||
| #ifdef TIME_WITH_SYS_TIME | ||||
| #include <time.h> | ||||
| #endif | ||||
| #else | ||||
| #ifdef HAVE_TIME_H | ||||
| #include <time.h> | ||||
| #endif | ||||
| #endif | ||||
|       ],[ | ||||
|         struct timeval ts; | ||||
|         ts.tv_sec  = 0; | ||||
|         ts.tv_usec = 0; | ||||
|       ]) | ||||
|     ],[ | ||||
|       ac_cv_struct_timeval="yes" | ||||
|     ],[ | ||||
|       ac_cv_struct_timeval="no" | ||||
|     ]) | ||||
|   ]) | ||||
|   case "$ac_cv_struct_timeval" in | ||||
|     yes) | ||||
|       AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1, | ||||
|         [Define to 1 if you have the timeval struct.]) | ||||
|       ;; | ||||
|   esac | ||||
| ]) # AC_DEFUN | ||||
|  | ||||
|  | ||||
| dnl CURL_CHECK_NONBLOCKING_SOCKET | ||||
| dnl ------------------------------------------------- | ||||
| dnl Check for how to set a socket to non-blocking state. There seems to exist | ||||
|   | ||||
							
								
								
									
										42
									
								
								ares/adig.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								ares/adig.c
									
									
									
									
									
								
							| @@ -1,4 +1,6 @@ | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * $Id$ | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|  * software and its documentation for any purpose and without | ||||
| @@ -153,8 +155,8 @@ int main(int argc, char **argv) | ||||
|   fd_set read_fds, write_fds; | ||||
|   struct timeval *tvp, tv; | ||||
|  | ||||
| #ifdef WIN32 | ||||
|   WORD wVersionRequested = MAKEWORD(1,1); | ||||
| #ifdef USE_WINSOCK | ||||
|   WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK); | ||||
|   WSADATA wsaData; | ||||
|   WSAStartup(wVersionRequested, &wsaData); | ||||
| #endif | ||||
| @@ -162,10 +164,16 @@ int main(int argc, char **argv) | ||||
|   options.flags = ARES_FLAG_NOCHECKRESP; | ||||
|   options.servers = NULL; | ||||
|   options.nservers = 0; | ||||
|   while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1) | ||||
|   while ((c = getopt(argc, argv, "df:s:c:t:T:U:")) != -1) | ||||
|     { | ||||
|       switch (c) | ||||
|         { | ||||
|         case 'd': | ||||
| #ifdef WATT32 | ||||
|           dbug_init(); | ||||
| #endif | ||||
|           break; | ||||
|  | ||||
|         case 'f': | ||||
|           /* Add a flag. */ | ||||
|           for (i = 0; i < nflags; i++) | ||||
| @@ -225,7 +233,7 @@ int main(int argc, char **argv) | ||||
|  | ||||
|         case 'T': | ||||
|           /* Set the TCP port number. */ | ||||
|           if (!isdigit((unsigned char)*optarg)) | ||||
|           if (!ISDIGIT(*optarg)) | ||||
|             usage(); | ||||
|           options.tcp_port = (unsigned short)strtol(optarg, NULL, 0); | ||||
|           optmask |= ARES_OPT_TCP_PORT; | ||||
| @@ -233,7 +241,7 @@ int main(int argc, char **argv) | ||||
|  | ||||
|         case 'U': | ||||
|           /* Set the UDP port number. */ | ||||
|           if (!isdigit((unsigned char)*optarg)) | ||||
|           if (!ISDIGIT(*optarg)) | ||||
|             usage(); | ||||
|           options.udp_port = (unsigned short)strtol(optarg, NULL, 0); | ||||
|           optmask |= ARES_OPT_UDP_PORT; | ||||
| @@ -396,7 +404,7 @@ static const unsigned char *display_question(const unsigned char *aptr, | ||||
|    */ | ||||
|   if (aptr + QFIXEDSZ > abuf + alen) | ||||
|     { | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -412,7 +420,7 @@ static const unsigned char *display_question(const unsigned char *aptr, | ||||
|   if (dnsclass != C_IN) | ||||
|     printf("\t%s", class_name(dnsclass)); | ||||
|   printf("\t%s\n", type_name(type)); | ||||
|   free(name); | ||||
|   ares_free_string(name); | ||||
|   return aptr; | ||||
| } | ||||
|  | ||||
| @@ -436,7 +444,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|    */ | ||||
|   if (aptr + RRFIXEDSZ > abuf + alen) | ||||
|     { | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -449,7 +457,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|   aptr += RRFIXEDSZ; | ||||
|   if (aptr + dlen > abuf + alen) | ||||
|     { | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -458,7 +466,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|   if (dnsclass != C_IN) | ||||
|     printf("\t%s", class_name(dnsclass)); | ||||
|   printf("\t%s", type_name(type)); | ||||
|   free(name); | ||||
|   ares_free_string(name); | ||||
|  | ||||
|   /* Display the RR data.  Don't touch aptr. */ | ||||
|   switch (type) | ||||
| @@ -476,7 +484,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t%s.", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       break; | ||||
|  | ||||
|     case T_HINFO: | ||||
| @@ -500,13 +508,13 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t%s.", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       p += len; | ||||
|       status = ares_expand_name(p, abuf, alen, &name, &len); | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t%s.", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       break; | ||||
|  | ||||
|     case T_MX: | ||||
| @@ -520,7 +528,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t%s.", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       break; | ||||
|  | ||||
|     case T_SOA: | ||||
| @@ -532,13 +540,13 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t%s.\n", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       p += len; | ||||
|       status = ares_expand_name(p, abuf, alen, &name, &len); | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t\t\t\t\t\t%s.\n", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       p += len; | ||||
|       if (p + 20 > aptr + dlen) | ||||
|         return NULL; | ||||
| @@ -592,7 +600,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, | ||||
|       if (status != ARES_SUCCESS) | ||||
|         return NULL; | ||||
|       printf("\t%s.", name); | ||||
|       free(name); | ||||
|       ares_free_string(name); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|   | ||||
							
								
								
									
										46
									
								
								ares/ahost.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								ares/ahost.c
									
									
									
									
									
								
							| @@ -1,4 +1,6 @@ | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * $Id$ | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|  * software and its documentation for any purpose and without | ||||
| @@ -30,6 +32,10 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #ifdef HAVE_GETOPT_H | ||||
| #include <getopt.h> | ||||
| #endif | ||||
|  | ||||
| #include "ares.h" | ||||
| #include "ares_dns.h" | ||||
| #include "inet_ntop.h" | ||||
| @@ -52,19 +58,40 @@ static void usage(void); | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|   ares_channel channel; | ||||
|   int status, nfds; | ||||
|   int status, nfds, c, addr_family = AF_INET; | ||||
|   fd_set read_fds, write_fds; | ||||
|   struct timeval *tvp, tv; | ||||
|   struct in_addr addr4; | ||||
|   struct in6_addr addr6; | ||||
|  | ||||
| #ifdef WIN32 | ||||
|   WORD wVersionRequested = MAKEWORD(1,1); | ||||
| #ifdef USE_WINSOCK | ||||
|   WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK); | ||||
|   WSADATA wsaData; | ||||
|   WSAStartup(wVersionRequested, &wsaData); | ||||
| #endif | ||||
|  | ||||
|   if (argc <= 1) | ||||
|   while ((c = getopt(argc,argv,"t:h")) != -1) | ||||
|     { | ||||
|       switch (c) | ||||
|         { | ||||
|         case 't': | ||||
|           if (!strcasecmp(optarg,"a")) | ||||
|             addr_family = AF_INET; | ||||
|           else if (!strcasecmp(optarg,"aaaa")) | ||||
|             addr_family = AF_INET6; | ||||
|           else | ||||
|             usage(); | ||||
|           break; | ||||
|         case 'h': | ||||
|         default: | ||||
|           usage(); | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   argc -= optind; | ||||
|   argv += optind; | ||||
|   if (argc < 1) | ||||
|     usage(); | ||||
|  | ||||
|   status = ares_init(&channel); | ||||
| @@ -75,7 +102,7 @@ int main(int argc, char **argv) | ||||
|     } | ||||
|  | ||||
|   /* Initiate the queries, one per command-line argument. */ | ||||
|   for (argv++; *argv; argv++) | ||||
|   for ( ; *argv; argv++) | ||||
|     { | ||||
|       if (ares_inet_pton(AF_INET, *argv, &addr4) == 1) | ||||
|         { | ||||
| @@ -89,8 +116,7 @@ int main(int argc, char **argv) | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           /* assume user wants A-records */ | ||||
|           ares_gethostbyname(channel, *argv, AF_INET, callback, *argv); | ||||
|           ares_gethostbyname(channel, *argv, addr_family, callback, *argv); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -132,8 +158,8 @@ static void callback(void *arg, int status, struct hostent *host) | ||||
|         { | ||||
|            int i; | ||||
|  | ||||
| 	   printf (", Aliases: "); | ||||
| 	   for (i = 0; host->h_aliases[i]; i++) | ||||
|            printf (", Aliases: "); | ||||
|            for (i = 0; host->h_aliases[i]; i++) | ||||
|                printf("%s ", host->h_aliases[i]); | ||||
|         } | ||||
| #endif | ||||
| @@ -143,6 +169,6 @@ static void callback(void *arg, int status, struct hostent *host) | ||||
|  | ||||
| static void usage(void) | ||||
| { | ||||
|   fprintf(stderr, "usage: ahost {host|addr} ...\n"); | ||||
|   fprintf(stderr, "usage: ahost [-t {a|aaaa}] {host|addr} ...\n"); | ||||
|   exit(1); | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -52,7 +54,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) | ||||
|  | ||||
|       /* Get the address part. */ | ||||
|       p = line; | ||||
|       while (*p && !isspace((unsigned char)*p)) | ||||
|       while (*p && !ISSPACE(*p)) | ||||
|         p++; | ||||
|       if (!*p) | ||||
|         continue; | ||||
| @@ -74,12 +76,12 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) | ||||
|  | ||||
|       /* Get the canonical hostname. */ | ||||
|       p++; | ||||
|       while (isspace((unsigned char)*p)) | ||||
|       while (ISSPACE(*p)) | ||||
|         p++; | ||||
|       if (!*p) | ||||
|         continue; | ||||
|       q = p; | ||||
|       while (*q && !isspace((unsigned char)*q)) | ||||
|       while (*q && !ISSPACE(*q)) | ||||
|         q++; | ||||
|       end_at_hostname = (*q == 0); | ||||
|       *q = 0; | ||||
| @@ -90,13 +92,13 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) | ||||
|         { | ||||
|           /* Count the aliases. */ | ||||
|           p = q + 1; | ||||
|           while (isspace((unsigned char)*p)) | ||||
|           while (ISSPACE(*p)) | ||||
|             p++; | ||||
|           while (*p) | ||||
|             { | ||||
|               while (*p && !isspace((unsigned char)*p)) | ||||
|               while (*p && !ISSPACE(*p)) | ||||
|                 p++; | ||||
|               while (isspace((unsigned char)*p)) | ||||
|               while (ISSPACE(*p)) | ||||
|                 p++; | ||||
|               naliases++; | ||||
|             } | ||||
| @@ -126,12 +128,12 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) | ||||
|       if (!end_at_hostname) | ||||
|         { | ||||
|           p = canonical + strlen(canonical) + 1; | ||||
|           while (isspace((unsigned char)*p)) | ||||
|           while (ISSPACE(*p)) | ||||
|             p++; | ||||
|           while (*p) | ||||
|             { | ||||
|               q = p; | ||||
|               while (*q && !isspace((unsigned char)*q)) | ||||
|               while (*q && !ISSPACE(*q)) | ||||
|                 q++; | ||||
|               hostent->h_aliases[naliases] = malloc(q - p + 1); | ||||
|               if (hostent->h_aliases[naliases] == NULL) | ||||
| @@ -139,7 +141,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) | ||||
|               memcpy(hostent->h_aliases[naliases], p, q - p); | ||||
|               hostent->h_aliases[naliases][q - p] = 0; | ||||
|               p = q; | ||||
|               while (isspace((unsigned char)*p)) | ||||
|               while (ISSPACE(*p)) | ||||
|                 p++; | ||||
|               naliases++; | ||||
|             } | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright (C) 2004 by Daniel Stenberg et al | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software and its | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -18,18 +18,6 @@ | ||||
| #ifndef ARES__DNS_H | ||||
| #define ARES__DNS_H | ||||
|  | ||||
| #ifdef ARES_BIG_ENDIAN | ||||
| /* big-endian aware versions */ | ||||
| #define DNS__16BIT(p)                   (((p)[1] << 8) | (p)[0]) | ||||
| #define DNS__32BIT(p)                   (((p)[3] << 24) | ((p)[2] << 16) | \ | ||||
|                                          ((p)[1] << 8) | (p)[0]) | ||||
| #define DNS__SET16BIT(p, v)             (((p)[1] = ((v) >> 8) & 0xff), \ | ||||
|                                          ((p)[0] = (v) & 0xff)) | ||||
| #define DNS__SET32BIT(p, v)             (((p)[3] = ((v) >> 24) & 0xff), \ | ||||
|                                          ((p)[2] = ((v) >> 16) & 0xff), \ | ||||
|                                          ((p)[1] = ((v) >> 8) & 0xff), \ | ||||
|                                          ((p)[0] = (v) & 0xff)) | ||||
| #else | ||||
| #define DNS__16BIT(p)                   (((p)[0] << 8) | (p)[1]) | ||||
| #define DNS__32BIT(p)                   (((p)[0] << 24) | ((p)[1] << 16) | \ | ||||
|                                          ((p)[2] << 8) | (p)[3]) | ||||
| @@ -39,7 +27,6 @@ | ||||
|                                          ((p)[1] = ((v) >> 16) & 0xff), \ | ||||
|                                          ((p)[2] = ((v) >> 8) & 0xff), \ | ||||
|                                          ((p)[3] = (v) & 0xff)) | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| /* we cannot use this approach on systems where we can't access 16/32 bit | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -53,13 +55,13 @@ int ares_expand_string(const unsigned char *encoded, | ||||
|   *s = malloc(len+1); | ||||
|   if (*s == NULL) | ||||
|     return ARES_ENOMEM; | ||||
|   q = *s;  | ||||
|   q = *s; | ||||
|   strncpy((char *)q, (char *)encoded, len); | ||||
|   q[len] = '\0'; | ||||
|  | ||||
|   *s = q; | ||||
|  | ||||
|   *enclen = len+1;  | ||||
|   *enclen = len+1; | ||||
|  | ||||
|   return ARES_SUCCESS; | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 2000 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -16,6 +18,7 @@ | ||||
| #include "setup.h" | ||||
| #include <stdlib.h> | ||||
| #include "ares.h" | ||||
| #include "ares_private.h" | ||||
|  | ||||
| void ares_free_string(void *str) | ||||
| { | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -170,7 +172,7 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen) | ||||
|     } | ||||
|   else if (status == ARES_ENODATA && hquery->family == AF_INET6) | ||||
|     { | ||||
|       /* There was no AAAA now lookup an A */ | ||||
|       /* There was no AAAA. Now lookup an A */ | ||||
|       hquery->family = AF_INET; | ||||
|       ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, | ||||
|                   hquery); | ||||
|   | ||||
| @@ -264,11 +264,11 @@ static char *lookup_service(unsigned short port, int flags, | ||||
|   char tmpbuf[4096]; | ||||
|  | ||||
|   if (port) | ||||
|     {  | ||||
|     { | ||||
|       if (flags & ARES_NI_NUMERICSERV) | ||||
|         sep = NULL; | ||||
|       else | ||||
|         {  | ||||
|         { | ||||
|           if (flags & ARES_NI_UDP) | ||||
|             proto = "udp"; | ||||
|           else if (flags & ARES_NI_SCTP) | ||||
| @@ -288,15 +288,15 @@ static char *lookup_service(unsigned short port, int flags, | ||||
| #elif GETSERVBYPORT_R_ARGS == 4 | ||||
|           if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0) | ||||
|             sep = NULL; | ||||
| #else      | ||||
| #else | ||||
|           /* Lets just hope the OS uses TLS! */ | ||||
|           sep = getservbyport(port, proto); | ||||
| #endif     | ||||
| #else      | ||||
| #endif | ||||
| #else | ||||
|           /* Lets just hope the OS uses TLS! */ | ||||
|           sep = getservbyport(port, proto); | ||||
| #endif     | ||||
|         }  | ||||
| #endif | ||||
|         } | ||||
|       if (sep && sep->s_name) | ||||
|         /* get service name */ | ||||
|         strcpy(tmpbuf, sep->s_name); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 2005 by Daniel Stenberg. | ||||
| /* Copyright (C) 2005 - 2006, Daniel Stenberg | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software and its | ||||
|  * documentation for any purpose and without fee is hereby granted, provided | ||||
| @@ -28,7 +28,6 @@ int ares_getsock(ares_channel channel, | ||||
|                  int numsocks) /* size of the 'socks' array */ | ||||
| { | ||||
|   struct server_state *server; | ||||
|   ares_socket_t nfds; | ||||
|   int i; | ||||
|   int sockindex=0; | ||||
|   int bitmap = 0; | ||||
| @@ -40,8 +39,9 @@ int ares_getsock(ares_channel channel, | ||||
|   if (!channel->queries) | ||||
|     return 0; | ||||
|  | ||||
|   nfds = 0; | ||||
|   for (i = 0; i < channel->nservers; i++) | ||||
|   for (i = 0; | ||||
|        (i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM); | ||||
|        i++) | ||||
|     { | ||||
|       server = &channel->servers[i]; | ||||
|       if (server->udp_socket != ARES_SOCKET_BAD) | ||||
| @@ -58,14 +58,13 @@ int ares_getsock(ares_channel channel, | ||||
|            break; | ||||
|          socks[sockindex] = server->tcp_socket; | ||||
|          bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); | ||||
|          sockindex++; | ||||
|  | ||||
|          if (server->qhead) { | ||||
|          if (server->qhead) | ||||
|            /* then the tcp socket is also writable! */ | ||||
|            bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex-1); | ||||
|          } | ||||
|            bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); | ||||
|  | ||||
|          sockindex++; | ||||
|        } | ||||
|     } | ||||
|   return (int)nfds; | ||||
|   return bitmap; | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -93,6 +95,16 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | ||||
|   struct server_state *server; | ||||
|   struct timeval tv; | ||||
|  | ||||
| #ifdef CURLDEBUG | ||||
|   const char *env = getenv("CARES_MEMDEBUG"); | ||||
|  | ||||
|   if (env) | ||||
|     curl_memdebug(env); | ||||
|   env = getenv("CARES_MEMLIMIT"); | ||||
|   if (env) | ||||
|     curl_memlimit(atoi(env)); | ||||
| #endif | ||||
|  | ||||
|   channel = malloc(sizeof(struct ares_channeldata)); | ||||
|   if (!channel) | ||||
|     return ARES_ENOMEM; | ||||
| @@ -361,7 +373,8 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size) | ||||
|     printf ("DNS Servers:\n" | ||||
|             "    %s (primary)\n", fi->DnsServerList.IpAddress.String); | ||||
|   } | ||||
|   if (inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE && | ||||
|   if (strlen(fi->DnsServerList.IpAddress.String) > 0 && | ||||
|       inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE && | ||||
|       left > ip_size) | ||||
|   { | ||||
|     ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String); | ||||
| @@ -737,7 +750,7 @@ static int config_domain(ares_channel channel, char *str) | ||||
|  | ||||
|   /* Set a single search domain. */ | ||||
|   q = str; | ||||
|   while (*q && !isspace((unsigned char)*q)) | ||||
|   while (*q && !ISSPACE(*q)) | ||||
|     q++; | ||||
|   *q = 0; | ||||
|   return set_search(channel, str); | ||||
| @@ -761,9 +774,9 @@ static int config_lookup(ares_channel channel, const char *str, | ||||
|         if (*p == *bindch) *l++ = 'b'; | ||||
|         else *l++ = 'f'; | ||||
|       } | ||||
|       while (*p && !isspace((unsigned char)*p) && (*p != ',')) | ||||
|       while (*p && !ISSPACE(*p) && (*p != ',')) | ||||
|         p++; | ||||
|       while (*p && (isspace((unsigned char)*p) || (*p == ','))) | ||||
|       while (*p && (ISSPACE(*p) || (*p == ','))) | ||||
|         p++; | ||||
|     } | ||||
|   *l = 0; | ||||
| @@ -788,7 +801,7 @@ static int config_nameserver(struct server_state **servers, int *nservers, | ||||
|   while (more) | ||||
|   { | ||||
|     more = 0; | ||||
|     while (*p && !isspace(*p) && *p != ',') | ||||
|     while (*p && !ISSPACE(*p) && *p != ',') | ||||
|       p++; | ||||
|  | ||||
|     if (*p) | ||||
| @@ -848,7 +861,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, | ||||
|       char ipbuf[16], ipbufpfx[32]; | ||||
|       /* Find just the IP */ | ||||
|       q = str; | ||||
|       while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q)) | ||||
|       while (*q && *q != '/' && *q != ';' && !ISSPACE(*q)) | ||||
|         q++; | ||||
|       memcpy(ipbuf, str, (int)(q-str)); | ||||
|       ipbuf[(int)(q-str)] = 0; | ||||
| @@ -856,7 +869,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, | ||||
|       if (*q == '/') | ||||
|         { | ||||
|           const char *str2 = q+1; | ||||
|           while (*q && *q != ';' && !isspace((unsigned char)*q)) | ||||
|           while (*q && *q != ';' && !ISSPACE(*q)) | ||||
|             q++; | ||||
|           memcpy(ipbufpfx, str, (int)(q-str)); | ||||
|           ipbufpfx[(int)(q-str)] = 0; | ||||
| @@ -905,11 +918,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           while (*q && *q != ';' && !isspace((unsigned char)*q)) | ||||
|           while (*q && *q != ';' && !ISSPACE(*q)) | ||||
|             q++; | ||||
|         } | ||||
|       str = q; | ||||
|       while (isspace((unsigned char)*str)) | ||||
|       while (ISSPACE(*str)) | ||||
|         str++; | ||||
|     } | ||||
|  | ||||
| @@ -935,9 +948,9 @@ static int set_search(ares_channel channel, const char *str) | ||||
|   p = str; | ||||
|   while (*p) | ||||
|     { | ||||
|       while (*p && !isspace((unsigned char)*p)) | ||||
|       while (*p && !ISSPACE(*p)) | ||||
|         p++; | ||||
|       while (isspace((unsigned char)*p)) | ||||
|       while (ISSPACE(*p)) | ||||
|         p++; | ||||
|       n++; | ||||
|     } | ||||
| @@ -953,7 +966,7 @@ static int set_search(ares_channel channel, const char *str) | ||||
|     { | ||||
|       channel->ndomains = n; | ||||
|       q = p; | ||||
|       while (*q && !isspace((unsigned char)*q)) | ||||
|       while (*q && !ISSPACE(*q)) | ||||
|         q++; | ||||
|       channel->domains[n] = malloc(q - p + 1); | ||||
|       if (!channel->domains[n]) | ||||
| @@ -961,7 +974,7 @@ static int set_search(ares_channel channel, const char *str) | ||||
|       memcpy(channel->domains[n], p, q - p); | ||||
|       channel->domains[n][q - p] = 0; | ||||
|       p = q; | ||||
|       while (isspace((unsigned char)*p)) | ||||
|       while (ISSPACE(*p)) | ||||
|         p++; | ||||
|       n++; | ||||
|     } | ||||
| @@ -978,7 +991,7 @@ static int set_options(ares_channel channel, const char *str) | ||||
|   while (*p) | ||||
|     { | ||||
|       q = p; | ||||
|       while (*q && !isspace((unsigned char)*q)) | ||||
|       while (*q && !ISSPACE(*q)) | ||||
|         q++; | ||||
|       val = try_option(p, q, "ndots:"); | ||||
|       if (val && channel->ndots == -1) | ||||
| @@ -990,7 +1003,7 @@ static int set_options(ares_channel channel, const char *str) | ||||
|       if (val && channel->tries == -1) | ||||
|         channel->tries = atoi(val); | ||||
|       p = q; | ||||
|       while (isspace((unsigned char)*p)) | ||||
|       while (ISSPACE(*p)) | ||||
|         p++; | ||||
|     } | ||||
|  | ||||
| @@ -1003,10 +1016,10 @@ static char *try_config(char *s, const char *opt) | ||||
|   size_t len; | ||||
|  | ||||
|   len = strlen(opt); | ||||
|   if (strncmp(s, opt, len) != 0 || !isspace((unsigned char)s[len])) | ||||
|   if (strncmp(s, opt, len) != 0 || !ISSPACE(s[len])) | ||||
|     return NULL; | ||||
|   s += len; | ||||
|   while (isspace((unsigned char)*s)) | ||||
|   while (ISSPACE(*s)) | ||||
|     s++; | ||||
|   return s; | ||||
| } | ||||
|   | ||||
| @@ -40,14 +40,14 @@ struct sockaddr_in6 | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_STRUCT_ADDRINFO | ||||
| struct addrinfo | ||||
| struct addrinfo  | ||||
| { | ||||
|   int ai_flags; | ||||
|   int ai_family; | ||||
|   int ai_socktype; | ||||
|   int ai_protocol; | ||||
|   size_t ai_addrlen; | ||||
|   char *ai_cannonname; | ||||
|   int              ai_flags; | ||||
|   int              ai_family; | ||||
|   int              ai_socktype; | ||||
|   int              ai_protocol; | ||||
|   socklen_t        ai_addrlen;   /* Follow rfc3493 struct addrinfo */ | ||||
|   char            *ai_canonname; | ||||
|   struct sockaddr *ai_addr; | ||||
|   struct addrinfo *ai_next; | ||||
| }; | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -30,6 +32,7 @@ | ||||
| #include <string.h> | ||||
| #include "ares.h" | ||||
| #include "ares_dns.h" | ||||
| #include "ares_private.h" | ||||
|  | ||||
| /* Header format, from RFC 1035: | ||||
|  *                                  1  1  1  1  1  1 | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 2005 Dominick Meglio | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| #ifndef __ARES_PRIVATE_H | ||||
| #define __ARES_PRIVATE_H | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
| @@ -199,3 +202,6 @@ int ares__read_line(FILE *fp, char **buf, int *bufsize); | ||||
|    this anyway for convenience. */ | ||||
| #include "../lib/memdebug.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* __ARES_PRIVATE_H */ | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -57,12 +59,13 @@ | ||||
| #define TRUE 1 | ||||
| #endif | ||||
|  | ||||
| #if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS) | ||||
| #ifdef USE_WINSOCK | ||||
| #define GET_ERRNO()  WSAGetLastError() | ||||
| #else | ||||
| #define GET_ERRNO()  errno | ||||
| #endif | ||||
|  | ||||
| static int try_again(int errnum); | ||||
| static void write_tcp_data(ares_channel channel, fd_set *write_fds, | ||||
|                            time_t now); | ||||
| static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now); | ||||
| @@ -94,6 +97,31 @@ void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) | ||||
|   process_timeouts(channel, now); | ||||
| } | ||||
|  | ||||
| /* Return 1 if the specified errno describes a readiness error, or 0 | ||||
|  * otherwise. This is mostly for HP-UX, which could return EAGAIN or | ||||
|  * EWOULDBLOCK. See this man page | ||||
|  * | ||||
|  * 	http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html?manpage=/usr/share/man/man2.Z/send.2 | ||||
|  */ | ||||
| static int try_again(int errnum) | ||||
| { | ||||
| #if !defined EWOULDBLOCK && !defined EAGAIN | ||||
| #error "Neither EWOULDBLOCK nor EAGAIN defined" | ||||
| #endif | ||||
|   switch (errnum) | ||||
|     { | ||||
| #ifdef EWOULDBLOCK | ||||
|     case EWOULDBLOCK: | ||||
|       return 1; | ||||
| #endif | ||||
| #if defined EAGAIN && EAGAIN != EWOULDBLOCK | ||||
|     case EAGAIN: | ||||
|       return 1; | ||||
| #endif | ||||
|     } | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| /* If any TCP sockets select true for writing, write out queued data | ||||
|  * we have for them. | ||||
|  */ | ||||
| @@ -132,11 +160,12 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) | ||||
|               vec[n].iov_len = sendreq->len; | ||||
|               n++; | ||||
|             } | ||||
|           wcount = writev(server->tcp_socket, vec, n); | ||||
|           wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n); | ||||
|           free(vec); | ||||
|           if (wcount < 0) | ||||
|             { | ||||
|               handle_error(channel, i, now); | ||||
|               if (!try_again(GET_ERRNO())) | ||||
|                   handle_error(channel, i, now); | ||||
|               continue; | ||||
|             } | ||||
|  | ||||
| @@ -168,12 +197,11 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) | ||||
|           /* Can't allocate iovecs; just send the first request. */ | ||||
|           sendreq = server->qhead; | ||||
|  | ||||
|           scount = send(server->tcp_socket, (void *)sendreq->data, | ||||
|                         sendreq->len, 0); | ||||
|  | ||||
|           scount = swrite(server->tcp_socket, sendreq->data, sendreq->len); | ||||
|           if (scount < 0) | ||||
|             { | ||||
|               handle_error(channel, i, now); | ||||
|               if (!try_again(GET_ERRNO())) | ||||
|                   handle_error(channel, i, now); | ||||
|               continue; | ||||
|             } | ||||
|  | ||||
| @@ -204,7 +232,8 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) | ||||
| static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) | ||||
| { | ||||
|   struct server_state *server; | ||||
|   int i, count; | ||||
|   int i; | ||||
|   ssize_t count; | ||||
|  | ||||
|   for (i = 0; i < channel->nservers; i++) | ||||
|     { | ||||
| @@ -219,16 +248,17 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) | ||||
|           /* We haven't yet read a length word, so read that (or | ||||
|            * what's left to read of it). | ||||
|            */ | ||||
|           count = recv(server->tcp_socket, | ||||
|                        (void *)(server->tcp_lenbuf + server->tcp_lenbuf_pos), | ||||
|                        2 - server->tcp_lenbuf_pos, 0); | ||||
|           count = sread(server->tcp_socket, | ||||
|                         server->tcp_lenbuf + server->tcp_lenbuf_pos, | ||||
|                         2 - server->tcp_lenbuf_pos); | ||||
|           if (count <= 0) | ||||
|             { | ||||
|               handle_error(channel, i, now); | ||||
|               if (!(count == -1 && try_again(GET_ERRNO()))) | ||||
|                   handle_error(channel, i, now); | ||||
|               continue; | ||||
|             } | ||||
|  | ||||
|           server->tcp_lenbuf_pos += count; | ||||
|           server->tcp_lenbuf_pos += (int)count; | ||||
|           if (server->tcp_lenbuf_pos == 2) | ||||
|             { | ||||
|               /* We finished reading the length word.  Decode the | ||||
| @@ -245,16 +275,17 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) | ||||
|       else | ||||
|         { | ||||
|           /* Read data into the allocated buffer. */ | ||||
|           count = recv(server->tcp_socket, | ||||
|                        (void *)(server->tcp_buffer + server->tcp_buffer_pos), | ||||
|                        server->tcp_length - server->tcp_buffer_pos, 0); | ||||
|           count = sread(server->tcp_socket, | ||||
|                         server->tcp_buffer + server->tcp_buffer_pos, | ||||
|                         server->tcp_length - server->tcp_buffer_pos); | ||||
|           if (count <= 0) | ||||
|             { | ||||
|               handle_error(channel, i, now); | ||||
|               if (!(count == -1 && try_again(GET_ERRNO()))) | ||||
|                   handle_error(channel, i, now); | ||||
|               continue; | ||||
|             } | ||||
|  | ||||
|           server->tcp_buffer_pos += count; | ||||
|           server->tcp_buffer_pos += (int)count; | ||||
|           if (server->tcp_buffer_pos == server->tcp_length) | ||||
|             { | ||||
|               /* We finished reading this answer; process it and | ||||
| @@ -266,6 +297,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) | ||||
|                         free(server->tcp_buffer); | ||||
|               server->tcp_buffer = NULL; | ||||
|               server->tcp_lenbuf_pos = 0; | ||||
|               server->tcp_buffer_pos = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -276,7 +308,8 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, | ||||
|                              time_t now) | ||||
| { | ||||
|   struct server_state *server; | ||||
|   int i, count; | ||||
|   int i; | ||||
|   ssize_t count; | ||||
|   unsigned char buf[PACKETSZ + 1]; | ||||
|  | ||||
|   for (i = 0; i < channel->nservers; i++) | ||||
| @@ -288,11 +321,13 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, | ||||
|           !FD_ISSET(server->udp_socket, read_fds)) | ||||
|         continue; | ||||
|  | ||||
|       count = recv(server->udp_socket, (void *)buf, sizeof(buf), 0); | ||||
|       if (count <= 0) | ||||
|       count = sread(server->udp_socket, buf, sizeof(buf)); | ||||
|       if (count == -1 && try_again(GET_ERRNO())) | ||||
|         continue; | ||||
|       else if (count <= 0) | ||||
|         handle_error(channel, i, now); | ||||
|  | ||||
|       process_answer(channel, buf, count, i, 0, now); | ||||
|       process_answer(channel, buf, (int)count, i, 0, now); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -476,9 +511,9 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) | ||||
|               return; | ||||
|             } | ||||
|         } | ||||
|       if (send(server->udp_socket, (void *)query->qbuf, | ||||
|                query->qlen, 0) == -1) | ||||
|       if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1) | ||||
|         { | ||||
|           /* FIXME: Handle EAGAIN here since it likely can happen. */ | ||||
|           query->skip_server[query->server] = 1; | ||||
|           next_server(channel, query, now); | ||||
|           return; | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
| @@ -237,15 +239,15 @@ static int single_domain(ares_channel channel, const char *name, char **s) | ||||
|                      == ARES_SUCCESS) | ||||
|                 { | ||||
|                   if (strncasecmp(line, name, len) != 0 || | ||||
|                       !isspace((unsigned char)line[len])) | ||||
|                       !ISSPACE(line[len])) | ||||
|                     continue; | ||||
|                   p = line + len; | ||||
|                   while (isspace((unsigned char)*p)) | ||||
|                   while (ISSPACE(*p)) | ||||
|                     p++; | ||||
|                   if (*p) | ||||
|                     { | ||||
|                       q = p + 1; | ||||
|                       while (*q && !isspace((unsigned char)*q)) | ||||
|                       while (*q && !ISSPACE(*q)) | ||||
|                         q++; | ||||
|                       *s = malloc(q - p + 1); | ||||
|                       if (*s) | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this | ||||
|   | ||||
| @@ -11,7 +11,15 @@ | ||||
|                        (ARES_VERSION_PATCH)) | ||||
| #define ARES_VERSION_STR "1.3.1" | ||||
|  | ||||
| #ifdef  __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| const char *ares_version(int *version); | ||||
|  | ||||
| #ifdef  __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") | ||||
|  * Copyright (c) 1996,1999 by Internet Software Consortium. | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| #ifndef __ARES_BITNCMP_H | ||||
| #define __ARES_BITNCMP_H | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* | ||||
| @@ -14,13 +17,10 @@ | ||||
|  * without express or implied warranty. | ||||
|  */ | ||||
|  | ||||
| #ifndef BITNCMP_H | ||||
| #define BITNCMP_H | ||||
|  | ||||
| #ifndef HAVE_BITNCMP | ||||
| int ares_bitncmp(const void *l, const void *r, int n); | ||||
| #else | ||||
| #define ares_bitncmp(x,y,z) bitncmp(x,y,z) | ||||
| #endif | ||||
|  | ||||
| #endif /* BITNCMP_H */ | ||||
| #endif /* __ARES_BITNCMP_H */ | ||||
|   | ||||
| @@ -29,6 +29,12 @@ | ||||
| #define HAVE_GETOPT_H 1 | ||||
| #endif | ||||
|  | ||||
| /* Define if you have the <sys/time.h> header file */ | ||||
| /* #define HAVE_SYS_TIME_H 1 */ | ||||
|  | ||||
| /* Define if you have the <time.h> header file.  */ | ||||
| #define HAVE_TIME_H 1 | ||||
|  | ||||
| /* Define if you have the <unistd.h> header file.  */ | ||||
| #if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ | ||||
|     defined(__POCC__) | ||||
| @@ -47,6 +53,16 @@ | ||||
| /* Define if you have the <ws2tcpip.h> header file.  */ | ||||
| #define HAVE_WS2TCPIP_H 1 | ||||
|  | ||||
| /* ---------------------------------------------------------------- */ | ||||
| /*                        OTHER HEADER INFO                         */ | ||||
| /* ---------------------------------------------------------------- */ | ||||
|  | ||||
| /* Define if you have the ANSI C header files.  */ | ||||
| #define STDC_HEADERS 1 | ||||
|  | ||||
| /* Define if you can safely include both <sys/time.h> and <time.h>.  */ | ||||
| /* #define TIME_WITH_SYS_TIME 1 */ | ||||
|  | ||||
| /* ---------------------------------------------------------------- */ | ||||
| /*                             FUNCTIONS                            */ | ||||
| /* ---------------------------------------------------------------- */ | ||||
| @@ -54,6 +70,63 @@ | ||||
| /* Define if you have the ioctlsocket function.  */ | ||||
| #define HAVE_IOCTLSOCKET 1 | ||||
|  | ||||
| /* Define if you have the getnameinfo function. */ | ||||
| #define HAVE_GETNAMEINFO 1 | ||||
|  | ||||
| /* Define to the type qualifier of arg 1 for getnameinfo. */ | ||||
| #define GETNAMEINFO_QUAL_ARG1 const | ||||
|  | ||||
| /* Define to the type of arg 1 for getnameinfo. */ | ||||
| #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * | ||||
|  | ||||
| /* Define to the type of arg 2 for getnameinfo. */ | ||||
| #define GETNAMEINFO_TYPE_ARG2 socklen_t | ||||
|  | ||||
| /* Define to the type of args 4 and 6 for getnameinfo. */ | ||||
| #define GETNAMEINFO_TYPE_ARG46 DWORD | ||||
|  | ||||
| /* Define to the type of arg 7 for getnameinfo. */ | ||||
| #define GETNAMEINFO_TYPE_ARG7 int | ||||
|  | ||||
| /* Define if you have the recv function. */ | ||||
| #define HAVE_RECV 1 | ||||
|  | ||||
| /* Define to the type of arg 1 for recv. */ | ||||
| #define RECV_TYPE_ARG1 SOCKET | ||||
|  | ||||
| /* Define to the type of arg 2 for recv. */ | ||||
| #define RECV_TYPE_ARG2 char * | ||||
|  | ||||
| /* Define to the type of arg 3 for recv. */ | ||||
| #define RECV_TYPE_ARG3 int | ||||
|  | ||||
| /* Define to the type of arg 4 for recv. */ | ||||
| #define RECV_TYPE_ARG4 int | ||||
|  | ||||
| /* Define to the function return type for recv. */ | ||||
| #define RECV_TYPE_RETV int | ||||
|  | ||||
| /* Define if you have the send function. */ | ||||
| #define HAVE_SEND 1 | ||||
|  | ||||
| /* Define to the type of arg 1 for send. */ | ||||
| #define SEND_TYPE_ARG1 SOCKET | ||||
|  | ||||
| /* Define to the type qualifier of arg 2 for send. */ | ||||
| #define SEND_QUAL_ARG2 const | ||||
|  | ||||
| /* Define to the type of arg 2 for send. */ | ||||
| #define SEND_TYPE_ARG2 char * | ||||
|  | ||||
| /* Define to the type of arg 3 for send. */ | ||||
| #define SEND_TYPE_ARG3 int | ||||
|  | ||||
| /* Define to the type of arg 4 for send. */ | ||||
| #define SEND_TYPE_ARG4 int | ||||
|  | ||||
| /* Define to the function return type for send. */ | ||||
| #define SEND_TYPE_RETV int | ||||
|  | ||||
| /* ---------------------------------------------------------------- */ | ||||
| /*                          STRUCT RELATED                          */ | ||||
| /* ---------------------------------------------------------------- */ | ||||
| @@ -64,6 +137,9 @@ | ||||
| /* Define this if you have struct sockaddr_storage */ | ||||
| #define HAVE_STRUCT_SOCKADDR_STORAGE 1 | ||||
|  | ||||
| /* Define this if you have struct timeval */ | ||||
| #define HAVE_STRUCT_TIMEVAL 1 | ||||
|  | ||||
| /* ---------------------------------------------------------------- */ | ||||
| /*                         IPV6 COMPATIBILITY                       */ | ||||
| /* ---------------------------------------------------------------- */ | ||||
|   | ||||
| @@ -16,10 +16,6 @@ solaris*) | ||||
| 	;; | ||||
| esac | ||||
|  | ||||
| AC_SEARCH_LIBS(gethostbyname, nsl) | ||||
| AC_SEARCH_LIBS(socket, socket) | ||||
|  | ||||
| dnl check for cygwin stuff | ||||
| AC_LIBTOOL_WIN32_DLL | ||||
|  | ||||
| dnl ************************************************************ | ||||
| @@ -81,6 +77,131 @@ esac | ||||
| AC_MSG_RESULT($need_no_undefined) | ||||
| AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes) | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Checks for libraries. | ||||
| dnl ********************************************************************** | ||||
|  | ||||
| dnl gethostbyname without lib or in the nsl lib? | ||||
| AC_CHECK_FUNC(gethostbyname, | ||||
|               [HAVE_GETHOSTBYNAME="1" | ||||
|               ], | ||||
|               [ AC_CHECK_LIB(nsl, gethostbyname, | ||||
|                              [HAVE_GETHOSTBYNAME="1" | ||||
|                              LIBS="$LIBS -lnsl" | ||||
|                              ]) | ||||
|               ]) | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   dnl gethostbyname in the socket lib? | ||||
|   AC_CHECK_LIB(socket, gethostbyname, | ||||
|                [HAVE_GETHOSTBYNAME="1" | ||||
|                LIBS="$LIBS -lsocket" | ||||
|                ]) | ||||
| fi | ||||
|  | ||||
| dnl At least one system has been identified to require BOTH nsl and socket | ||||
| dnl libs at the same time to link properly. | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   AC_MSG_CHECKING([for gethostbyname with both nsl and socket libs]) | ||||
|   my_ac_save_LIBS=$LIBS | ||||
|   LIBS="-lnsl -lsocket $LIBS" | ||||
|   AC_TRY_LINK( , | ||||
|              [gethostbyname();], | ||||
|              [ dnl found it! | ||||
|              HAVE_GETHOSTBYNAME="1" | ||||
|              AC_MSG_RESULT([yes])], | ||||
|              [ dnl failed! | ||||
|              AC_MSG_RESULT([no]) | ||||
|              dnl restore LIBS | ||||
|              LIBS=$my_ac_save_LIBS] | ||||
|              ) | ||||
| fi | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   dnl This is for Msys/Mingw | ||||
|   AC_MSG_CHECKING([for gethostbyname in ws2_32]) | ||||
|   my_ac_save_LIBS=$LIBS | ||||
|   LIBS="-lws2_32 $LIBS" | ||||
|   AC_TRY_LINK([#include <winsock2.h>], | ||||
|                [gethostbyname("www.dummysite.com");], | ||||
|                [ dnl worked! | ||||
|                ws2="yes" | ||||
|                AC_MSG_RESULT([yes]) | ||||
|                HAVE_GETHOSTBYNAME="1"], | ||||
|                [ dnl failed, restore LIBS | ||||
|                LIBS=$my_ac_save_LIBS | ||||
|                AC_MSG_RESULT(no)] | ||||
|              ) | ||||
| fi | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   dnl This is for eCos with a stubbed DNS implementation | ||||
|   AC_MSG_CHECKING([for gethostbyname for eCos]) | ||||
|   AC_TRY_LINK([ | ||||
| #include <stdio.h> | ||||
| #include <netdb.h>], | ||||
|                [gethostbyname("www.dummysite.com");], | ||||
|                [ dnl worked! | ||||
|                AC_MSG_RESULT([yes]) | ||||
|                HAVE_GETHOSTBYNAME="1"], | ||||
|                AC_MSG_RESULT(no) | ||||
|              ) | ||||
| fi | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   dnl gethostbyname in the net lib - for BeOS | ||||
|   AC_CHECK_LIB(net, gethostbyname, | ||||
|                [HAVE_GETHOSTBYNAME="1" | ||||
|                LIBS="$LIBS -lnet" | ||||
|                ]) | ||||
| fi | ||||
|  | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" = "1"; then | ||||
|   AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname]) | ||||
| else | ||||
|   AC_MSG_ERROR([couldn't find libraries for gethostbyname()]) | ||||
| fi | ||||
|  | ||||
| dnl resolve lib? | ||||
| AC_CHECK_FUNC(strcasecmp, , [ AC_CHECK_LIB(resolve, strcasecmp) ]) | ||||
|  | ||||
| if test "$ac_cv_lib_resolve_strcasecmp" = "$ac_cv_func_strcasecmp"; then | ||||
|   AC_CHECK_LIB(resolve, strcasecmp, | ||||
|               [LIBS="-lresolve $LIBS"], | ||||
|                , | ||||
|                -lnsl) | ||||
| fi | ||||
|  | ||||
| dnl socket lib? | ||||
| AC_CHECK_FUNC(connect, , [ AC_CHECK_LIB(socket, connect) ]) | ||||
|  | ||||
| dnl dl lib? | ||||
| AC_CHECK_FUNC(dlclose, , [ AC_CHECK_LIB(dl, dlopen) ]) | ||||
|  | ||||
| AC_MSG_CHECKING([whether to use libgcc]) | ||||
| AC_ARG_ENABLE(libgcc, | ||||
| AC_HELP_STRING([--enable-libgcc],[use libgcc when linking]), | ||||
| [ case "$enableval" in | ||||
|   yes) | ||||
|         LIBS="$LIBS -lgcc" | ||||
|        AC_MSG_RESULT(yes) | ||||
|        ;; | ||||
|   *)   AC_MSG_RESULT(no) | ||||
|        ;; | ||||
|   esac ], | ||||
|        AC_MSG_RESULT(no) | ||||
| ) | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| dnl Back to "normal" configuring | ||||
| dnl ********************************************************************** | ||||
|  | ||||
| dnl Checks for header files. | ||||
| AC_HEADER_STDC | ||||
|  | ||||
| @@ -96,6 +217,8 @@ CURL_CHECK_HEADER_WINSOCK | ||||
| CURL_CHECK_HEADER_WINSOCK2 | ||||
| CURL_CHECK_HEADER_WS2TCPIP | ||||
|  | ||||
| CURL_CHECK_HEADER_MALLOC | ||||
|  | ||||
| dnl check for a few basic system headers we need | ||||
| AC_CHECK_HEADERS( | ||||
|        sys/types.h \ | ||||
| @@ -142,6 +265,7 @@ dnl Checks for typedefs, structures, and compiler characteristics. | ||||
| AC_C_CONST | ||||
| AC_TYPE_SIZE_T | ||||
| AC_HEADER_TIME | ||||
| CURL_CHECK_STRUCT_TIMEVAL | ||||
|  | ||||
| AC_CHECK_SIZEOF(size_t) | ||||
| AC_CHECK_SIZEOF(long) | ||||
| @@ -173,6 +297,11 @@ TYPE_IN_ADDR_T | ||||
|  | ||||
| TYPE_SOCKADDR_STORAGE | ||||
|  | ||||
| CURL_CHECK_FUNC_RECV | ||||
|  | ||||
| CURL_CHECK_FUNC_SEND | ||||
|  | ||||
| CURL_CHECK_MSG_NOSIGNAL | ||||
|  | ||||
| dnl check for AF_INET6 | ||||
| CARES_CHECK_CONSTANT( | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") | ||||
|  * Copyright (c) 1996,1999 by Internet Software Consortium. | ||||
| @@ -77,14 +79,13 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) | ||||
|  | ||||
|   ch = *src++; | ||||
|   if (ch == '0' && (src[0] == 'x' || src[0] == 'X') | ||||
|       && isascii((unsigned char)(src[1])) | ||||
|       && isxdigit((unsigned char)(src[1]))) { | ||||
|       && ISXDIGIT(src[1])) { | ||||
|     /* Hexadecimal: Eat nybble string. */ | ||||
|     if (size <= 0U) | ||||
|       goto emsgsize; | ||||
|     dirty = 0; | ||||
|     src++;  /* skip x or X. */ | ||||
|     while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { | ||||
|     while ((ch = *src++) != '\0' && ISXDIGIT(ch)) { | ||||
|       if (isupper(ch)) | ||||
|         ch = tolower(ch); | ||||
|       n = (int)(strchr(xdigits, ch) - xdigits); | ||||
| @@ -104,7 +105,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) | ||||
|         goto emsgsize; | ||||
|       *dst++ = (unsigned char) (tmp << 4); | ||||
|     } | ||||
|   } else if (isascii(ch) && isdigit(ch)) { | ||||
|   } else if (ISDIGIT(ch)) { | ||||
|     /* Decimal: eat dotted digit string. */ | ||||
|     for (;;) { | ||||
|       tmp = 0; | ||||
| @@ -115,7 +116,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) | ||||
|         if (tmp > 255) | ||||
|           goto enoent; | ||||
|       } while ((ch = *src++) != '\0' && | ||||
|                isascii(ch) && isdigit(ch)); | ||||
|                ISDIGIT(ch)); | ||||
|       if (size-- <= 0U) | ||||
|         goto emsgsize; | ||||
|       *dst++ = (unsigned char) tmp; | ||||
| @@ -124,15 +125,15 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) | ||||
|       if (ch != '.') | ||||
|         goto enoent; | ||||
|       ch = *src++; | ||||
|       if (!isascii(ch) || !isdigit(ch)) | ||||
|       if (!ISDIGIT(ch)) | ||||
|         goto enoent; | ||||
|     } | ||||
|   } else | ||||
|     goto enoent; | ||||
|  | ||||
|   bits = -1; | ||||
|   if (ch == '/' && isascii((unsigned char)(src[0])) && | ||||
|       isdigit((unsigned char)(src[0])) && dst > odst) { | ||||
|   if (ch == '/' && | ||||
|       ISDIGIT(src[0]) && dst > odst) { | ||||
|     /* CIDR width specifier.  Nothing can follow it. */ | ||||
|     ch = *src++;    /* Skip over the /. */ | ||||
|     bits = 0; | ||||
| @@ -140,7 +141,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) | ||||
|       n = (int)(strchr(digits, ch) - digits); | ||||
|       bits *= 10; | ||||
|       bits += n; | ||||
|     } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); | ||||
|     } while ((ch = *src++) != '\0' && ISDIGIT(ch)); | ||||
|     if (ch != '\0') | ||||
|       goto enoent; | ||||
|     if (bits > 32) | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| #ifndef __ARES_INET_NET_PTON_H | ||||
| #define __ARES_INET_NET_PTON_H | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* | ||||
| @@ -14,9 +17,6 @@ | ||||
|  * without express or implied warranty. | ||||
|  */ | ||||
|  | ||||
| #ifndef INET_NET_PTON_H | ||||
| #define INET_NET_PTON_H | ||||
|  | ||||
| #if defined(HAVE_INET_PTON) && defined(HAVE_INET_PTON_IPV6) | ||||
| #define ares_inet_pton(x,y,z) inet_pton(x,y,z) | ||||
| #else | ||||
| @@ -28,4 +28,4 @@ int ares_inet_pton(int af, const char *src, void *dst); | ||||
| int ares_inet_net_pton(int af, const char *src, void *dst, size_t size); | ||||
| #endif | ||||
|  | ||||
| #endif /* INET_NET_PTON_H */ | ||||
| #endif /* __ARES_INET_NET_PTON_H */ | ||||
|   | ||||
| @@ -129,9 +129,13 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) | ||||
|    * Keep this in mind if you think this function should have been coded | ||||
|    * to use pointer overlays.  All the world's not a VAX. | ||||
|    */ | ||||
|   char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; | ||||
|   struct { int base, len; } best = { 0,0 }, cur = { 0,0 }; | ||||
|   unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; | ||||
|   char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; | ||||
|   char *tp; | ||||
|   struct { | ||||
|     long base; | ||||
|     long len; | ||||
|   } best, cur; | ||||
|   unsigned long words[NS_IN6ADDRSZ / NS_INT16SZ]; | ||||
|   int i; | ||||
|  | ||||
|   /* | ||||
| @@ -139,11 +143,15 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) | ||||
|    *  Copy the input (bytewise) array into a wordwise array. | ||||
|    *  Find the longest run of 0x00's in src[] for :: shorthanding. | ||||
|    */ | ||||
|   memset(words, '\0', sizeof words); | ||||
|   memset(words, '\0', sizeof(words)); | ||||
|   for (i = 0; i < NS_IN6ADDRSZ; i++) | ||||
|       words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); | ||||
|  | ||||
|   best.base = -1; | ||||
|   cur.base = -1; | ||||
|   best.len = 0; | ||||
|   cur.len = 0; | ||||
|  | ||||
|   for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) | ||||
|     { | ||||
|       if (words[i] == 0) | ||||
| @@ -192,12 +200,12 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) | ||||
|       if (i == 6 && best.base == 0 && | ||||
|           (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) | ||||
|         { | ||||
|           if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) | ||||
|           if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) | ||||
|             return (NULL); | ||||
|           tp += strlen(tp); | ||||
|           break; | ||||
|         } | ||||
|         tp += SPRINTF((tp, "%x", words[i])); | ||||
|         tp += SPRINTF((tp, "%lx", words[i])); | ||||
|     } | ||||
|  | ||||
|   /* Was it a trailing run of 0x00's? */ | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| #ifndef __ARES_INET_NTOP_H | ||||
| #define __ARES_INET_NTOP_H | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* | ||||
| @@ -14,13 +17,10 @@ | ||||
|  * without express or implied warranty. | ||||
|  */ | ||||
|  | ||||
| #ifndef INET_NTOP_H | ||||
| #define INET_NTOP_H | ||||
|  | ||||
| #ifdef HAVE_INET_NTOP | ||||
| #if defined(HAVE_INET_NTOP) && defined(HAVE_INET_NTOP_IPV6) | ||||
| #define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z) | ||||
| #else | ||||
| const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size); | ||||
| #endif | ||||
|  | ||||
| #endif /* INET_NET_NTOP_H */ | ||||
| #endif /* __ARES_INET_NTOP_H */ | ||||
|   | ||||
| @@ -7,7 +7,9 @@ | ||||
|    port build */ | ||||
|  | ||||
| #ifndef NETWARE | ||||
| #ifndef __CYGWIN__ | ||||
| #include <windows.h> | ||||
| #endif | ||||
| #include <process.h> /* for the _getpid() proto */ | ||||
| #endif  /* !NETWARE */ | ||||
| #include <sys/types.h> | ||||
|   | ||||
							
								
								
									
										34
									
								
								ares/setup.h
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								ares/setup.h
									
									
									
									
									
								
							| @@ -1,6 +1,8 @@ | ||||
| #ifndef __ARES_SETUP_H | ||||
| #define __ARES_SETUP_H | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright (C) 2004 - 2005 by Daniel Stenberg et al | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software and its | ||||
| @@ -43,7 +45,11 @@ | ||||
|  * Include header files for windows builds before redefining anything. | ||||
|  * Use this preproessor block only to include or exclude windows.h, | ||||
|  * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs | ||||
|  * to any other further and independant block. | ||||
|  * to any other further and independant block.  Under Cygwin things work | ||||
|  * just as under linux (e.g. <sys/socket.h>) and the winsock headers should | ||||
|  * never be included when __CYGWIN__ is defined.  configure script takes | ||||
|  * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H, | ||||
|  * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined. | ||||
|  */ | ||||
|  | ||||
| #ifdef HAVE_WINDOWS_H | ||||
| @@ -63,6 +69,22 @@ | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else | ||||
|  * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else | ||||
|  * undefine USE_WINSOCK. | ||||
|  */ | ||||
|  | ||||
| #undef USE_WINSOCK | ||||
|  | ||||
| #ifdef HAVE_WINSOCK2_H | ||||
| #  define USE_WINSOCK 2 | ||||
| #else | ||||
| #  ifdef HAVE_WINSOCK_H | ||||
| #    define USE_WINSOCK 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Work-arounds for systems without configure support | ||||
|  */ | ||||
| @@ -99,7 +121,7 @@ | ||||
|  * Typedef our socket type | ||||
|  */ | ||||
|  | ||||
| #if defined(WIN32) && !defined(WATT32) | ||||
| #ifdef USE_WINSOCK | ||||
| typedef SOCKET ares_socket_t; | ||||
| #define ARES_SOCKET_BAD INVALID_SOCKET | ||||
| #else | ||||
| @@ -145,4 +167,12 @@ int ares_strcasecmp(const char *s1, const char *s2); | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Include macros and defines that should only be processed once. | ||||
|  */ | ||||
|  | ||||
| #ifndef __SETUP_ONCE_H | ||||
| #include "setup_once.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* __ARES_SETUP_H */ | ||||
|   | ||||
							
								
								
									
										127
									
								
								ares/setup_once.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								ares/setup_once.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| #ifndef __SETUP_ONCE_H | ||||
| #define __SETUP_ONCE_H | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* Copyright (C) 2004 - 2006 by Daniel Stenberg et al | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software and its | ||||
|  * documentation for any purpose and without fee is hereby granted, provided | ||||
|  * that the above copyright notice appear in all copies and that both that | ||||
|  * copyright notice and this permission notice appear in supporting | ||||
|  * documentation, and that the name of M.I.T. not be used in advertising or | ||||
|  * publicity pertaining to distribution of the software without specific, | ||||
|  * written prior permission.  M.I.T. makes no representations about the | ||||
|  * suitability of this software for any purpose.  It is provided "as is" | ||||
|  * without express or implied warranty. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /******************************************************************** | ||||
|  *                              NOTICE                              * | ||||
|  *                             ========                             * | ||||
|  *                                                                  * | ||||
|  *  Content of header files lib/setup_once.h and ares/setup_once.h  * | ||||
|  *  must be kept in sync. Modify the other one if you change this.  * | ||||
|  *                                                                  * | ||||
|  ********************************************************************/ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * If we have the MSG_NOSIGNAL define, make sure we use | ||||
|  * it as the fourth argument of send() and recv() | ||||
|  */ | ||||
|  | ||||
| #ifdef HAVE_MSG_NOSIGNAL | ||||
| #define SEND_4TH_ARG MSG_NOSIGNAL | ||||
| #else | ||||
| #define SEND_4TH_ARG 0 | ||||
| #endif  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * The definitions for the return type and arguments types | ||||
|  * of functions recv() and send() belong and come from the | ||||
|  * configuration file. Do not define them in any other place. | ||||
|  * | ||||
|  * HAVE_RECV is defined if you have a function named recv() | ||||
|  * which is used to read incoming data from sockets. If your | ||||
|  * function has another name then don't define HAVE_RECV. | ||||
|  * | ||||
|  * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2, | ||||
|  * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also | ||||
|  * be defined. | ||||
|  * | ||||
|  * HAVE_SEND is defined if you have a function named send() | ||||
|  * which is used to write outgoing data on a connected socket. | ||||
|  * If yours has another name then don't define HAVE_SEND. | ||||
|  * | ||||
|  * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2, | ||||
|  * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and | ||||
|  * SEND_TYPE_RETV must also be defined. | ||||
|  */ | ||||
|  | ||||
| #ifdef HAVE_RECV | ||||
| #if !defined(RECV_TYPE_ARG1) || \ | ||||
|     !defined(RECV_TYPE_ARG2) || \ | ||||
|     !defined(RECV_TYPE_ARG3) || \ | ||||
|     !defined(RECV_TYPE_ARG4) || \ | ||||
|     !defined(RECV_TYPE_RETV) | ||||
|   /* */ | ||||
|   Error Missing_definition_of_return_and_arguments_types_of_recv | ||||
|   /* */ | ||||
| #else | ||||
| #define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ | ||||
|                                    (RECV_TYPE_ARG2)(y), \ | ||||
|                                    (RECV_TYPE_ARG3)(z), \ | ||||
|                                    (RECV_TYPE_ARG4)(SEND_4TH_ARG)) | ||||
| #endif | ||||
| #else /* HAVE_RECV */ | ||||
| #ifndef sread | ||||
|   /* */ | ||||
|   Error Missing_definition_of_macro_sread | ||||
|   /* */ | ||||
| #endif | ||||
| #endif /* HAVE_RECV */ | ||||
|  | ||||
| #ifdef HAVE_SEND | ||||
| #if !defined(SEND_TYPE_ARG1) || \ | ||||
|     !defined(SEND_QUAL_ARG2) || \ | ||||
|     !defined(SEND_TYPE_ARG2) || \ | ||||
|     !defined(SEND_TYPE_ARG3) || \ | ||||
|     !defined(SEND_TYPE_ARG4) || \ | ||||
|     !defined(SEND_TYPE_RETV) | ||||
|   /* */ | ||||
|   Error Missing_definition_of_return_and_arguments_types_of_send | ||||
|   /* */ | ||||
| #else | ||||
| #define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ | ||||
|                                     (SEND_TYPE_ARG2)(y), \ | ||||
|                                     (SEND_TYPE_ARG3)(z), \ | ||||
|                                     (SEND_TYPE_ARG4)(SEND_4TH_ARG)) | ||||
| #endif | ||||
| #else /* HAVE_SEND */ | ||||
| #ifndef swrite | ||||
|   /* */ | ||||
|   Error Missing_definition_of_macro_swrite | ||||
|   /* */ | ||||
| #endif | ||||
| #endif /* HAVE_SEND */ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Uppercase macro versions of ANSI/ISO is*() functions/macros which  | ||||
|  * avoid negative number inputs with argument byte codes > 127. | ||||
|  */ | ||||
|  | ||||
| #define ISSPACE(x)  (isspace((int)  ((unsigned char)x))) | ||||
| #define ISDIGIT(x)  (isdigit((int)  ((unsigned char)x))) | ||||
| #define ISALNUM(x)  (isalnum((int)  ((unsigned char)x))) | ||||
| #define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) | ||||
| #define ISGRAPH(x)  (isgraph((int)  ((unsigned char)x))) | ||||
| #define ISALPHA(x)  (isalpha((int)  ((unsigned char)x))) | ||||
| #define ISPRINT(x)  (isprint((int)  ((unsigned char)x))) | ||||
|  | ||||
|  | ||||
| #endif /* __SETUP_ONCE_H */ | ||||
|  | ||||
| @@ -1,5 +1,7 @@ | ||||
| #include "setup.h" | ||||
|  | ||||
| /* $Id$ */ | ||||
|  | ||||
| /* only do the following on windows | ||||
|  */ | ||||
| #if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS) | ||||
| @@ -100,6 +102,6 @@ ares_writev (ares_socket_t s, const struct iovec *vector, size_t count) | ||||
|     memcpy (bp, vector[i].iov_base, vector[i].iov_len); | ||||
|     bp += vector[i].iov_len; | ||||
|   } | ||||
|   return send (s, (const void*)buffer, bytes, 0); | ||||
|   return (int)swrite(s, buffer, bytes); | ||||
| } | ||||
| #endif /* WIN32 builds only */ | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| #                            | (__| |_| |  _ <| |___ | ||||
| #                             \___|\___/|_| \_\_____| | ||||
| # | ||||
| # Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||
| # Copyright (C) 1998 - 2006, 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 | ||||
| @@ -140,7 +140,7 @@ else | ||||
|   libtoolize=`findtool $LIBTOOLIZE` | ||||
| fi | ||||
|  | ||||
| lt_pversion=`$libtool --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'` | ||||
| lt_pversion=`$libtool --version 2>/dev/null|head -n 2|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'` | ||||
| if test -z "$lt_pversion"; then | ||||
|   echo "buildconf: libtool not found." | ||||
|   echo "            You need libtool version $LIBTOOL_WANTED_VERSION or newer installed" | ||||
|   | ||||
							
								
								
									
										84
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -28,7 +28,7 @@ dnl We don't know the version number "staticly" so we use a dash here | ||||
| AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/]) | ||||
|  | ||||
| dnl configure script copyright | ||||
| AC_COPYRIGHT([Copyright (c) 1998 - 2005 Daniel Stenberg, <daniel@haxx.se> | ||||
| AC_COPYRIGHT([Copyright (c) 1998 - 2006 Daniel Stenberg, <daniel@haxx.se> | ||||
| This configure script may be copied, distributed and modified under the  | ||||
| terms of the curl license; see COPYING for more details]) | ||||
|  | ||||
| @@ -373,6 +373,21 @@ then | ||||
|              ) | ||||
| fi | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   dnl This is for eCos with a stubbed DNS implementation | ||||
|   AC_MSG_CHECKING([for gethostbyname for eCos]) | ||||
|   AC_TRY_LINK([ | ||||
| #include <stdio.h> | ||||
| #include <netdb.h>], | ||||
|                [gethostbyname("www.dummysite.com");], | ||||
|                [ dnl worked! | ||||
|                AC_MSG_RESULT([yes]) | ||||
|                HAVE_GETHOSTBYNAME="1"], | ||||
|                AC_MSG_RESULT(no) | ||||
|              ) | ||||
| fi | ||||
|  | ||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | ||||
| then | ||||
|   dnl gethostbyname in the net lib - for BeOS | ||||
| @@ -537,10 +552,6 @@ main() | ||||
|  | ||||
| if test "$ipv6" = "yes"; then | ||||
|   curl_ipv6_msg="enabled" | ||||
|  | ||||
|   CURL_CHECK_WORKING_GETADDRINFO | ||||
|  | ||||
|   CURL_CHECK_NI_WITHSCOPEID | ||||
| fi | ||||
|  | ||||
| dnl ********************************************************************** | ||||
| @@ -736,7 +747,7 @@ AC_ARG_WITH(gssapi-includes, | ||||
| AC_ARG_WITH(gssapi-libs, | ||||
|   AC_HELP_STRING([--with-gssapi-libs=DIR], | ||||
|   		 [Specify location of GSSAPI libs]), | ||||
|   [ GSSAPI_LIBS="-L$withval" | ||||
|   [ GSSAPI_LIB_DIR="-L$withval" | ||||
|     want_gss="yes" ] | ||||
| ) | ||||
|  | ||||
| @@ -1447,6 +1458,7 @@ dnl ********************************************************************** | ||||
| dnl Checks for header files. | ||||
| AC_HEADER_STDC | ||||
|  | ||||
| CURL_CHECK_HEADER_MALLOC | ||||
|  | ||||
| dnl Now check for the very most basic headers. Then we can use these | ||||
| dnl ones as default-headers when checking for the rest! | ||||
| @@ -1458,7 +1470,6 @@ AC_CHECK_HEADERS( | ||||
|         sys/ioctl.h \ | ||||
|         assert.h \ | ||||
|         unistd.h \ | ||||
|         malloc.h \ | ||||
|         stdlib.h \ | ||||
|         limits.h \ | ||||
|         arpa/inet.h \ | ||||
| @@ -1516,6 +1527,8 @@ dnl Checks for typedefs, structures, and compiler characteristics. | ||||
| AC_C_CONST | ||||
| AC_TYPE_SIZE_T | ||||
| AC_HEADER_TIME | ||||
| CURL_CHECK_STRUCT_TIMEVAL | ||||
| CURL_VERIFY_RUNTIMELIBS | ||||
|  | ||||
| AC_CHECK_SIZEOF(curl_off_t, ,[ | ||||
| #include <stdio.h> | ||||
| @@ -1553,6 +1566,12 @@ TYPE_SOCKADDR_STORAGE | ||||
|  | ||||
| AC_FUNC_SELECT_ARGTYPES | ||||
|  | ||||
| CURL_CHECK_FUNC_RECV | ||||
|  | ||||
| CURL_CHECK_FUNC_SEND | ||||
|  | ||||
| CURL_CHECK_MSG_NOSIGNAL | ||||
|  | ||||
| dnl Checks for library functions. | ||||
| dnl AC_PROG_GCC_TRADITIONAL | ||||
| AC_TYPE_SIGNAL | ||||
| @@ -1689,6 +1708,11 @@ dnl Check if the getnameinfo function is available | ||||
| dnl and get the types of five of its arguments. | ||||
| CURL_CHECK_FUNC_GETNAMEINFO | ||||
|  | ||||
| if test "$ipv6" = "yes"; then | ||||
|   CURL_CHECK_WORKING_GETADDRINFO | ||||
|   CURL_CHECK_NI_WITHSCOPEID | ||||
| fi | ||||
|  | ||||
| AC_MSG_CHECKING([if we are Mac OS X (to disable poll)]) | ||||
| disable_poll=no | ||||
| case $host in | ||||
| @@ -1954,6 +1978,52 @@ AC_HELP_STRING([--disable-cookies],[Disable cookies support]), | ||||
|        AC_MSG_RESULT(yes) | ||||
| ) | ||||
|  | ||||
| dnl ************************************************************ | ||||
| dnl Enable hiding of internal symbols in library to reduce its size and | ||||
| dnl speed dynamic linking of applications.  This currently is only supported | ||||
| dnl on gcc >= 4.0 and SunPro C. | ||||
| dnl | ||||
| AC_MSG_CHECKING([whether to enable hidden symbols in the library]) | ||||
| AC_ARG_ENABLE(hidden-symbols, | ||||
| AC_HELP_STRING([--enable-hidden-symbols],[Hide internal symbols in library]) | ||||
| AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibility in library]), | ||||
| [ case "$enableval" in | ||||
|   no) | ||||
|        AC_MSG_RESULT(no) | ||||
|        ;; | ||||
|   *)    | ||||
|        AC_MSG_CHECKING([whether $CC supports it]) | ||||
|        if test "$GCC" = yes ; then | ||||
|          if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then | ||||
| 	   AC_MSG_RESULT(yes) | ||||
| 	   AC_DEFINE(CURL_HIDDEN_SYMBOLS, 1, [to enable hidden symbols]) | ||||
| 	   AC_SUBST(CURL_HIDDEN_SYMBOLS) | ||||
| 	   AC_DEFINE(CURL_EXTERN_SYMBOL, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) | ||||
| 	   AC_SUBST(CURL_EXTERN_SYMBOL) | ||||
| 	   CFLAGS="$CFLAGS -fvisibility=hidden" | ||||
|          else | ||||
|             AC_MSG_RESULT(no) | ||||
|           fi | ||||
|  | ||||
|        else | ||||
|        	 dnl Test for SunPro cc | ||||
|        	 if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then | ||||
|            AC_MSG_RESULT(yes) | ||||
| 	   AC_DEFINE(CURL_HIDDEN_SYMBOLS, 1, [to enable hidden symbols]) | ||||
| 	   AC_SUBST(CURL_HIDDEN_SYMBOLS) | ||||
| 	   AC_DEFINE(CURL_EXTERN_SYMBOL, [__global], [to make a symbol visible]) | ||||
| 	   AC_SUBST(CURL_EXTERN_SYMBOL) | ||||
| 	   CFLAGS="$CFLAGS -xldscope=hidden" | ||||
|          else | ||||
|            AC_MSG_RESULT(no) | ||||
|          fi | ||||
|        fi | ||||
|        ;; | ||||
|   esac ], | ||||
|        AC_MSG_RESULT(no) | ||||
| ) | ||||
|  | ||||
| dnl ************************************************************ | ||||
| if test "x$ws2" = "xyes"; then | ||||
|  | ||||
|   dnl If ws2_32 is wanted, make sure it is the _last_ lib in LIBS (makes | ||||
|   | ||||
| @@ -46,8 +46,8 @@ Cocoa | ||||
|  | ||||
| D | ||||
|  | ||||
|   Written by Charles Sanders and James Wavro | ||||
|   http://www.atari-soldiers.com/libcurl.html | ||||
|   Written by Kenneth Bogert | ||||
|   http://curl.haxx.se/libcurl/d/ | ||||
|  | ||||
| Dylan | ||||
|  | ||||
| @@ -155,6 +155,11 @@ S-Lang | ||||
|   S-Lang binding written by John E Davis | ||||
|   http://www.jedsoft.org/slang/modules/curl.html | ||||
|  | ||||
| Smalltalk | ||||
|  | ||||
|   Smalltalk binding written by Danil Osipchuk | ||||
|   http://www.squeaksource.com/CurlPlugin/ | ||||
|  | ||||
| SPL | ||||
|  | ||||
|   SPL binding written by Clifford Wolf | ||||
|   | ||||
| @@ -87,7 +87,6 @@ FTP | ||||
|  - via http-proxy | ||||
|  - all operations can be tunneled through a http-proxy | ||||
|  - customizable to retrieve file modification date | ||||
|  - third party transfers | ||||
|  - no dir depth limit | ||||
|  | ||||
| FTPS (*1) | ||||
|   | ||||
							
								
								
									
										142
									
								
								docs/INSTALL
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								docs/INSTALL
									
									
									
									
									
								
							| @@ -16,7 +16,6 @@ Installing Binary Packages | ||||
|  | ||||
| UNIX | ||||
| ==== | ||||
|  | ||||
|    A normal unix installation is made in three or four steps (after you've | ||||
|    unpacked the source archive): | ||||
|  | ||||
| @@ -129,6 +128,19 @@ UNIX | ||||
|      If you're a curl developer and use gcc, you might want to enable more | ||||
|      debug options with the --enable-debug option. | ||||
|  | ||||
|      curl can be built to use a whole range of libraries to provide various | ||||
|      useful services, and configure will try to auto-detect a decent | ||||
|      default. But if you want to alter it, you can select how to deal with | ||||
|      each individual library. | ||||
|  | ||||
|      To build with GnuTLS support instead of OpenSSL for SSL/TLS, note that | ||||
|      you need to use both --without-ssl and --with-gnutls. | ||||
|  | ||||
|      To build with yassl support instead of OpenSSL or GunTLS, you must build | ||||
|      yassl with its OpenSSL emulation enabled and point to that directory root | ||||
|      with configure --with-ssl. | ||||
|  | ||||
|  | ||||
| Win32 | ||||
| ===== | ||||
|  | ||||
| @@ -280,7 +292,6 @@ Win32 | ||||
|  | ||||
| IBM OS/2 | ||||
| ======== | ||||
|  | ||||
|    Building under OS/2 is not much different from building under unix. | ||||
|    You need: | ||||
|  | ||||
| @@ -308,6 +319,7 @@ IBM OS/2 | ||||
|    If you're getting huge binaries, probably your makefiles have the -g in | ||||
|    CFLAGS. | ||||
|  | ||||
|  | ||||
| VMS | ||||
| === | ||||
|    (The VMS section is in whole contributed by the friendly Nico Baggus) | ||||
| @@ -378,6 +390,7 @@ VMS | ||||
|    13-jul-2001 | ||||
|    N. Baggus | ||||
|  | ||||
|  | ||||
| QNX | ||||
| === | ||||
|    (This section was graciously brought to us by David Bentham) | ||||
| @@ -429,17 +442,16 @@ AmigaOS | ||||
|  | ||||
| NetWare | ||||
| ======= | ||||
|  | ||||
|    To compile curl.nlm / libcurl.nlm you need: | ||||
|    - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later. | ||||
|    - gnu make and awk running on the platform you compile on; | ||||
|      native Win32 versions can be downloaded from: | ||||
|      http://www.gknw.com/development/prgtools/ | ||||
|      http://www.gknw.net/development/prgtools/ | ||||
|    - recent Novell LibC SDK available from: | ||||
|      http://developer.novell.com/ndk/libc.htm | ||||
|    - optional zlib sources (at the moment only dynamic linking with zlib.imp); | ||||
|      sources with NetWare Makefile can be obtained from: | ||||
|      http://www.gknw.com/mirror/zlib/ | ||||
|      http://www.gknw.net/mirror/zlib/ | ||||
|    - optional OpenSSL sources (version 0.9.8 or later which builds with BSD); | ||||
|  | ||||
|    Set a search path to your compiler, linker and tools; on Linux make | ||||
| @@ -453,14 +465,101 @@ NetWare | ||||
|    with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked... | ||||
|    Any help in testing appreciated! | ||||
|    Builds automatically created 8 times a day from current CVS are here: | ||||
|    http://www.gknw.com/mirror/curl/autobuilds/ | ||||
|    http://www.gknw.net/mirror/curl/autobuilds/ | ||||
|    the status of these builds can be viewed at the autobuild table: | ||||
|    http://curl.haxx.se/auto/ | ||||
|  | ||||
|  | ||||
| eCos | ||||
| ==== | ||||
|    curl does not use the eCos build system, so you must first build eCos | ||||
|    separately, then link curl to the resulting eCos library.  Here's a sample | ||||
|    configure line to do so on an x86 Linux box targeting x86: | ||||
|  | ||||
|    GCCLIB=`gcc -print-libgcc-file-name` && \ | ||||
|    CFLAGS="-D__ECOS=1 -nostdinc -I$ECOS_INSTALL/include \ | ||||
|     -I`dirname $GCCLIB`/include" \ | ||||
|    LDFLAGS="-nostdlib -Wl,--gc-sections -Wl,-static \ | ||||
|     -L$ECOS_INSTALL/lib -Ttarget.ld -ltarget" \ | ||||
|    ./configure --host=i386 --disable-shared \ | ||||
|     --without-ssl --without-zlib --disable-manual --disable-ldap | ||||
|  | ||||
|    In most cases, eCos users will be using libcurl from within a custom | ||||
|    embedded application.  Using the standard 'curl' executable from | ||||
|    within eCos means facing the limitation of the standard eCos C | ||||
|    startup code which does not allow passing arguments in main().  To | ||||
|    run 'curl' from eCos and have it do something useful, you will need | ||||
|    to either modify the eCos startup code to pass in some arguments, or | ||||
|    modify the curl application itself to retrieve its arguments from | ||||
|    some location set by the bootloader or hard-code them. | ||||
|  | ||||
|    Something like the following patch could be used to hard-code some | ||||
|    arguments.  The MTAB_ENTRY line mounts a RAM disk as the root filesystem | ||||
|    (without mounting some kind of filesystem, eCos errors out all file | ||||
|    operations which curl does not take to well).  The next section synthesizes | ||||
|    some command-line arguments for curl to use, in this case to direct curl | ||||
|    to read further arguments from a file.  It then creates that file on the | ||||
|    RAM disk and places within it a URL to download: a file: URL that | ||||
|    just happens to point to the configuration file itself.  The results | ||||
|    of running curl in this way is the contents of the configuration file | ||||
|    printed to the console. | ||||
|  | ||||
| --- src/main.c	19 Jul 2006 19:09:56 -0000	1.363 | ||||
| +++ src/main.c	24 Jul 2006 21:37:23 -0000 | ||||
| @@ -4286,11 +4286,31 @@ | ||||
|  } | ||||
|   | ||||
|   | ||||
| +#ifdef __ECOS | ||||
| +#include <cyg/fileio/fileio.h> | ||||
| +MTAB_ENTRY( testfs_mte1, | ||||
| +                   "/", | ||||
| +                   "ramfs", | ||||
| +                   "", | ||||
| +                   0); | ||||
| +#endif | ||||
|   | ||||
|  int main(int argc, char *argv[]) | ||||
|  { | ||||
|    int res; | ||||
|    struct Configurable config; | ||||
| +#ifdef __ECOS | ||||
| +  char *args[] = {"ecos-curl", "-K", "curlconf.txt"}; | ||||
| +  FILE *f; | ||||
| +  argc = sizeof(args)/sizeof(args[0]); | ||||
| +  argv = args; | ||||
| + | ||||
| +  f = fopen("curlconf.txt", "w"); | ||||
| +  if (f) { | ||||
| +    fprintf(f, "--url file:curlconf.txt"); | ||||
| +    fclose(f); | ||||
| +  } | ||||
| +#endif | ||||
|    memset(&config, 0, sizeof(struct Configurable)); | ||||
|   | ||||
|    config.errors = stderr; /* default errors to stderr */ | ||||
|  | ||||
|  | ||||
| Minix | ||||
| ===== | ||||
|    curl can be compiled on Minix 3 using gcc (ACK has a few problems due | ||||
|    to mismatched headers and libraries as of ver. 3.1.2).  The gcc and bash | ||||
|    packages must be installed first.  The default heap size allocated to | ||||
|    bash is inadequate for running configure and will result in out of memory | ||||
|    errors.  Increase it with the command: | ||||
|  | ||||
|      chmem =2048000 /usr/local/bin/bash | ||||
|  | ||||
|    Make sure gcc and bash are in the PATH then configure curl with a | ||||
|    command like this: | ||||
|  | ||||
|      ./configure GREP=/usr/bin/grep AR=/usr/gnu/bin/gar --disable-ldap | ||||
|  | ||||
|    Then simply run 'make'. | ||||
|  | ||||
|  | ||||
| CROSS COMPILE | ||||
| ============= | ||||
|  | ||||
|    (This section was graciously brought to us by Jim Duey, with additions by | ||||
|    Dan Fandrich) | ||||
|  | ||||
| @@ -506,13 +605,17 @@ CROSS COMPILE | ||||
|  | ||||
|        ./configure --host=ARCH-OS | ||||
|  | ||||
|  | ||||
| REDUCING SIZE | ||||
| ============= | ||||
|    There are a number of configure options that can be used to reduce the | ||||
|    size of libcurl for embedded applications where binary size is an | ||||
|    important factor.  First, be sure to set the CFLAGS environment variable | ||||
|    when configuring with any compiler optimization flags to reduce the | ||||
|    size of the binary.  For gcc, this would mean at minimum: | ||||
|    important factor.  First, be sure to set the CFLAGS variable when | ||||
|    configuring with any relevant compiler optimization flags to reduce the | ||||
|    size of the binary.  For gcc, this would mean at minimum the -Os option | ||||
|    and probably the -march=X option as well, e.g.: | ||||
|  | ||||
|       env CFLAGS='-Os' ./configure ... | ||||
|       ./configure CFLAGS='-Os' ... | ||||
|  | ||||
|    Be sure to specify as many --disable- and --without- flags on the configure | ||||
|    command-line as you can to disable all the libcurl features that you | ||||
| @@ -526,10 +629,24 @@ CROSS COMPILE | ||||
|      --disable-crypto-auth (disables HTTP cryptographic authentication) | ||||
|      --disable-ipv6 (disables support for IPv6) | ||||
|      --disable-verbose (eliminates debugging strings and error code strings) | ||||
|      --enable-hidden-symbols (eliminates unneeded symbols in the shared library) | ||||
|      --without-libidn (disables support for the libidn DNS library) | ||||
|      --without-ssl (disables support for SSL/TLS) | ||||
|      --without-zlib (disables support for on-the-fly decompression) | ||||
|  | ||||
|    The GNU linker has a number of options to reduce the size of the libcurl | ||||
|    dynamic libraries on some platforms even further. Specify them by giving | ||||
|    the options -Wl,-Bsymbolic and -Wl,-s on the gcc command-line.   | ||||
|    Be sure also to strip debugging symbols from your binaries after | ||||
|    compiling using 'strip' (or the appropriate variant if cross-compiling). | ||||
|    If space is really tight, you may be able to remove some unneeded | ||||
|    sections of the shared library using the -R option to objcopy (e.g. the | ||||
|    .comment section). | ||||
|  | ||||
|    Using these techniques it is possible to create an HTTP-only shared | ||||
|    libcurl library for i386 Linux platforms that is less than 90 KB in | ||||
|    size (as of version 7.15.4). | ||||
|  | ||||
|    You may find that statically linking libcurl to your application will | ||||
|    result in a lower total size. | ||||
|  | ||||
| @@ -567,12 +684,15 @@ PORTS | ||||
|         - StrongARM/ARM7/ARM9 Linux 2.4, 2.6 | ||||
|         - StrongARM NetBSD 1.4.1 | ||||
|         - Ultrix 4.3a | ||||
|         - UNICOS 9.0 | ||||
|         - i386 BeOS | ||||
|         - i386 DOS | ||||
|         - i386 eCos 1.3.1 | ||||
|         - i386 Esix 4.1 | ||||
|         - i386 FreeBSD | ||||
|         - i386 HURD | ||||
|         - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 | ||||
|         - i386 MINIX 3.1.2 | ||||
|         - i386 NetBSD | ||||
|         - i386 Novell NetWare | ||||
|         - i386 OS/2 | ||||
|   | ||||
| @@ -3,7 +3,12 @@ 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! | ||||
|  | ||||
| 34. The SOCKS connection codes don't properly acknowledge (connect) timeouts. | ||||
| 35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very | ||||
|   bad when used with the multi interface. | ||||
|  | ||||
| 34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts. | ||||
|   Also see #12. According to bug #1556528, even the SOCKS5 connect code does | ||||
|   not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528, | ||||
|  | ||||
| 33. Doing multi-pass HTTP authentication on a non-default port does not work. | ||||
|   This happens because the multi-pass code abuses the redirect following code | ||||
| @@ -42,8 +47,7 @@ may have been fixed since this was written! | ||||
| 25. When doing a CONNECT request with curl it doesn't properly handle if the | ||||
|   proxy closes the connection within the authentication "negotiation phase". | ||||
|   Like if you do HTTPS or similar over a proxy and you use perhaps | ||||
|   --proxy-anyauth. There's work in progress on this problem, and a recent | ||||
|   patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html | ||||
|   --proxy-anyauth. | ||||
|  | ||||
| 23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy. | ||||
|   We don't have any test cases for SOCKS proxy. We probably have even more | ||||
| @@ -68,9 +72,6 @@ may have been fixed since this was written! | ||||
|  | ||||
|    Since 7.15.4 at least line endings are converted. | ||||
|  | ||||
| 19. FTP 3rd party transfers with the multi interface doesn't work. Test: | ||||
|   define CURL_MULTIEASY, rebuild curl, run test case 230 - 232. | ||||
|  | ||||
| 16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>, | ||||
|   <password>, and <fpath> components, encoded as "%00".  The problem is that | ||||
|   curl_unescape does not detect this, but instead returns a shortened C | ||||
| @@ -92,7 +93,7 @@ may have been fixed since this was written! | ||||
|  | ||||
| 12. When connecting to a SOCKS proxy, the (connect) timeout is not properly | ||||
|   acknowledged after the actual TCP connect (during the SOCKS "negotiate" | ||||
|   phase). Pointed out by Lucas. Fix: need to select() and timeout properly. | ||||
|   phase). | ||||
|  | ||||
| 11. Using configure --disable-[protocol] may cause 'make test' to fail for | ||||
|   tests using the disabled protocol(s). | ||||
| @@ -103,10 +104,6 @@ may have been fixed since this was written! | ||||
|   http://curl.haxx.se/bug/view.cgi?id=1004841. How? | ||||
|   http://curl.haxx.se/mail/lib-2004-08/0182.html | ||||
|  | ||||
| 9. --limit-rate using -d or -F does not work. This is because the limit logic | ||||
|   is provided by the curl app in its read/write callbacks, and when doing | ||||
|   -d/-F the callbacks aren't used! http://curl.haxx.se/bug/view.cgi?id=921395 | ||||
|  | ||||
| 8. Doing resumed upload over HTTP does not work with '-C -', because curl | ||||
|   doesn't do a HEAD first to get the initial size. This needs to be done | ||||
|   manually for HTTP PUT resume to work, and then '-C [index]'. | ||||
|   | ||||
| @@ -32,7 +32,8 @@ OpenSSL http://www.openssl.org/source/license.html | ||||
|         are not allowed to ship binaries that link with OpenSSL that includes | ||||
|         GPL code (unless that specific GPL code includes an exception for | ||||
|         OpenSSL - a habit that is growing more and more common). If OpenSSL's | ||||
|         licensing is a problem for you, consider using GnuTLS instead. | ||||
|         licensing is a problem for you, consider using GnuTLS or yassl | ||||
|         instead. | ||||
|  | ||||
| GnuTLS  http://www.gnutls.org/ | ||||
|  | ||||
| @@ -41,6 +42,11 @@ GnuTLS  http://www.gnutls.org/ | ||||
|         GnuTLS itself depends on and uses other libs (libgcrypt and | ||||
|         libgpg-error) and they too are LGPL- or GPL-licensed. | ||||
|  | ||||
| yassl   http://www.yassl.com/ | ||||
|  | ||||
|         (May be used for SSL/TLS support) Uses the GPL[1] license. If this is | ||||
|         a problem for you, consider using OpenSSL or GnuTLS instead. | ||||
|  | ||||
| c-ares  http://daniel.haxx.se/projects/c-ares/license.html | ||||
|  | ||||
|         (Used for asynchronous name resolves) Uses an MIT license that is very | ||||
|   | ||||
							
								
								
									
										31
									
								
								docs/MANUAL
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								docs/MANUAL
									
									
									
									
									
								
							| @@ -31,6 +31,15 @@ SIMPLE USAGE | ||||
|  | ||||
|         curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/ | ||||
|  | ||||
|   Get a file off an FTPS server: | ||||
|  | ||||
|         curl ftps://files.are.secure.com/secrets.txt | ||||
|  | ||||
|   or use the more appropriate FTPS way to get the same file: | ||||
|  | ||||
|         curl --ftp-ssl ftp://files.are.secure.com/secrets.txt | ||||
|  | ||||
|  | ||||
| DOWNLOAD TO A FILE | ||||
|  | ||||
|   Get a web page and store in a local file: | ||||
| @@ -64,6 +73,10 @@ USING PASSWORDS | ||||
|    It is just like for FTP, but you may also want to specify and use | ||||
|    SSL-specific options for certificates etc. | ||||
|  | ||||
|    Note that using FTPS:// as prefix is the "implicit" way as described in the | ||||
|    standards while the recommended "explicit" way is done by using FTP:// and | ||||
|    the --ftp-ssl option. | ||||
|  | ||||
|  HTTP | ||||
|  | ||||
|    The HTTP URL doesn't support user and password in the URL string. Curl | ||||
| @@ -105,6 +118,8 @@ PROXY | ||||
|  | ||||
|         curl -U user:passwd -x my-proxy:888 http://www.get.this/ | ||||
|  | ||||
|  curl also supports SOCKS4 and SOCKS5 proxies with --socks4 and --socks5. | ||||
|  | ||||
|  See also the environment variables Curl support that offer further proxy | ||||
|  control. | ||||
|  | ||||
| @@ -846,6 +861,22 @@ PERSISTENT CONNECTIONS | ||||
|   transfers faster. If you use a http proxy for file transfers, practically | ||||
|   all transfers will be persistent. | ||||
|  | ||||
| MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE | ||||
|  | ||||
|   As is mentioned above, you can download multiple files with one command line | ||||
|   by simply adding more URLs. If you want those to get saved to a local file | ||||
|   instead of just printed to stdout, you need to add one save option for each | ||||
|   URL you specify. Note that this also goes for the -O option. | ||||
|  | ||||
|   For example: get two files and use -O for the first and a custom file | ||||
|   name for the second: | ||||
|  | ||||
|     curl -O http://url.com/file.txt ftp://ftp.com/moo.exe -o moo.jpg | ||||
|  | ||||
|   You can also upload multiple files in a similar fashion: | ||||
|  | ||||
|     curl -T local1 ftp://ftp.com/moo.exe -T local2 ftp://ftp.com/moo2.txt | ||||
|  | ||||
| MAILING LISTS | ||||
|  | ||||
|   For your convenience, we have several open mailing lists to discuss curl, | ||||
|   | ||||
							
								
								
									
										23
									
								
								docs/THANKS
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								docs/THANKS
									
									
									
									
									
								
							| @@ -8,6 +8,7 @@ Adrian Schuur | ||||
| Alan Pinstein | ||||
| Albert Chin-A-Young | ||||
| Albert Choy | ||||
| Ale Vesely | ||||
| Aleksandar Milivojevic | ||||
| Alex Neblett | ||||
| Alex Suykov | ||||
| @@ -20,6 +21,7 @@ Alexis Carvalho | ||||
| Amol Pattekar | ||||
| Andi Jahja | ||||
| Andreas Damm | ||||
| Andreas Ntaflos | ||||
| Andreas Olsson | ||||
| Andreas Rieke | ||||
| Andres Garcia | ||||
| @@ -34,6 +36,8 @@ Angus Mackay | ||||
| Antoine Calando | ||||
| Anton Kalmykov | ||||
| Arkadiusz Miskiewicz | ||||
| Arve Knudsen | ||||
| Ates Goral | ||||
| Augustus Saunders | ||||
| Avery Fay | ||||
| Ben Greear | ||||
| @@ -47,6 +51,7 @@ Brad Burdick | ||||
| Bradford Bruce | ||||
| Brent Beardsley | ||||
| Brian Akins | ||||
| Brian Dessent | ||||
| Brian R Duffy | ||||
| Bruce Mitchener | ||||
| Bryan Henderson | ||||
| @@ -77,6 +82,7 @@ Damien Adant | ||||
| Dan Becker | ||||
| Dan C | ||||
| Dan Fandrich | ||||
| Dan Nelson | ||||
| Dan Torop | ||||
| Dan Zitter | ||||
| Daniel Stenberg | ||||
| @@ -189,6 +195,8 @@ Ian Wilkes | ||||
| Ignacio Vazquez-Abrams | ||||
| Igor Polyakov | ||||
| Ilguiz Latypov | ||||
| Ilja van Sprundel | ||||
| Ingmar Runge | ||||
| Ingo Ralf Blum | ||||
| Ingo Wilken | ||||
| Jacky Lam | ||||
| @@ -203,6 +211,7 @@ Jamie Lokier | ||||
| Jamie Newton | ||||
| Jamie Wilkinson | ||||
| Jan Kunder | ||||
| Jari Sundell | ||||
| Jason S. Priebe | ||||
| Jaz Fresh | ||||
| Jean Jacques Drouin | ||||
| @@ -249,6 +258,7 @@ Kai-Uwe Rommel | ||||
| Kang-Jin Lee | ||||
| Karl Moerder | ||||
| Karol Pietrzak | ||||
| Katie Wang | ||||
| Keith MacDonald | ||||
| Keith McGuigan | ||||
| Ken Hirsch | ||||
| @@ -286,6 +296,7 @@ Lucas Adamski | ||||
| Lukasz Czekierda | ||||
| Luke Call | ||||
| Luong Dinh Dung | ||||
| Maciej Karpiuk | ||||
| Maciej W. Rozycki | ||||
| Marc Boucher | ||||
| Marcelo Juchem  | ||||
| @@ -294,6 +305,8 @@ Marco G. Salvagno | ||||
| Marcus Webster | ||||
| Mario Schroeder | ||||
| Mark Butler | ||||
| Mark Eichin | ||||
| Mark Lentczner | ||||
| Markus Koetter | ||||
| Markus Moeller | ||||
| Markus Oberhumer | ||||
| @@ -314,11 +327,14 @@ Mettgut Jamalla | ||||
| Michael Benedict | ||||
| Michael Curtis | ||||
| Michael Jahn | ||||
| Michael Jerris | ||||
| Michael Mealling | ||||
| Michael Wallner | ||||
| Michal Bonino | ||||
| Michal Marek | ||||
| Michele Bini | ||||
| Mihai Ionescu | ||||
| Mikael Sennerholm | ||||
| Mike Bytnar | ||||
| Mike Dobbs | ||||
| Miklos Nemeth | ||||
| @@ -343,6 +359,7 @@ Nis Jorgensen | ||||
| Nodak Sodak | ||||
| Norbert Novotny | ||||
| Ofer | ||||
| Olaf St<53>ben | ||||
| Oren Tirosh | ||||
| P R Schaffner | ||||
| Patrick Bihan-Faou | ||||
| @@ -351,6 +368,7 @@ Paul Harrington | ||||
| Paul Marquis | ||||
| Paul Moore | ||||
| Paul Nolan | ||||
| Paul Querna | ||||
| Pavel Cenek | ||||
| Pavel Orehov | ||||
| Pawel A. Gajda | ||||
| @@ -360,6 +378,7 @@ Peter Bray | ||||
| Peter Forret | ||||
| Peter Heuchert | ||||
| Peter Pentchev | ||||
| Peter Silva | ||||
| Peter Su | ||||
| Peter Sylvester | ||||
| Peter Todd | ||||
| @@ -400,7 +419,9 @@ Robert D. Young | ||||
| Robert Olson | ||||
| Robert Weaver | ||||
| Robin Kay | ||||
| Robson Braga Araujo | ||||
| Rodney Simmons | ||||
| Roland Blom | ||||
| Roland Krikava | ||||
| Roland Zimmermann | ||||
| Roman Koifman | ||||
| @@ -490,8 +511,10 @@ Wesley Laxton | ||||
| Wez Furlong | ||||
| Wilfredo Sanchez | ||||
| Wojciech Zwiefka | ||||
| Xavier Bouchoux | ||||
| Yang Tse | ||||
| Yarram Sunil | ||||
| Yves Lejeune | ||||
| Zvi Har'El  | ||||
| nk | ||||
| swalkaus at yahoo.com | ||||
|   | ||||
| @@ -115,10 +115,6 @@ TODO | ||||
|  | ||||
|  HTTP | ||||
|  | ||||
|  * Pipelining. Sending multiple requests before the previous one(s) are done. | ||||
|    This could possibly be implemented using the multi interface to queue | ||||
|    requests and the response data. | ||||
|  | ||||
|  * When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has | ||||
|    never been reported as causing trouble to anyone, but should be considered | ||||
|    to use the HTTP version the user has chosen. | ||||
| @@ -135,6 +131,10 @@ TODO | ||||
|  | ||||
|  SSL | ||||
|  | ||||
|  * Provide a libcurl API for setting mutex callbacks in the underlying SSL | ||||
|    library, so that the same application code can use mutex-locking | ||||
|    independently of OpenSSL or GnutTLS being used. | ||||
|  | ||||
|  * Anton Fedorov's "dumpcert" patch: | ||||
|    http://curl.haxx.se/mail/lib-2004-03/0088.html | ||||
|  | ||||
|   | ||||
							
								
								
									
										103
									
								
								docs/curl.1
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								docs/curl.1
									
									
									
									
									
								
							| @@ -21,7 +21,7 @@ | ||||
| .\" * $Id$ | ||||
| .\" ************************************************************************** | ||||
| .\" | ||||
| .TH curl 1 "21 Mar 2006" "Curl 7.15.4" "Curl Manual" | ||||
| .TH curl 1 "23 Sep 2006" "Curl 7.16.0" "Curl Manual" | ||||
| .SH NAME | ||||
| curl \- transfer a URL | ||||
| .SH SYNOPSIS | ||||
| @@ -34,9 +34,9 @@ protocols (HTTP, HTTPS, FTP, FTPS, TFTP, DICT, TELNET, LDAP or FILE). | ||||
| The command is designed to work without user interaction. | ||||
|  | ||||
| curl offers a busload of useful tricks like proxy support, user | ||||
| authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file | ||||
| transfer resume and more. As you will see below, the amount of features will | ||||
| make your head spin! | ||||
| authentication, ftp upload, HTTP post, SSL connections, cookies, file transfer | ||||
| resume and more. As you will see below, the amount of features will make your | ||||
| head spin! | ||||
|  | ||||
| curl is powered by libcurl for all transfer-related features. See | ||||
| .BR libcurl (3) | ||||
| @@ -312,25 +312,25 @@ run curl. | ||||
|  | ||||
| If this option is used several times, each occurrence will toggle this on/off. | ||||
| .IP "--egd-file <file>" | ||||
| (HTTPS) Specify the path name to the Entropy Gathering Daemon socket. The | ||||
| socket is used to seed the random engine for SSL connections. See also the | ||||
| (SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket | ||||
| is used to seed the random engine for SSL connections. See also the | ||||
| \fI--random-file\fP option. | ||||
| .IP "-E/--cert <certificate[:password]>" | ||||
| (HTTPS) | ||||
| Tells curl to use the specified certificate file when getting a file | ||||
| with HTTPS. The certificate must be in PEM format. | ||||
| If the optional password isn't specified, it will be queried for on | ||||
| the terminal. Note that this certificate is the private key and the private | ||||
| certificate concatenated! | ||||
| (SSL) Tells curl to use the specified certificate file when getting a file | ||||
| with HTTPS or FTPS. The certificate must be in PEM format.  If the optional | ||||
| password isn't specified, it will be queried for on the terminal. Note that | ||||
| this option assumes a \&"certificate" file that is the private key and the | ||||
| private certificate concatenated! See \fI--cert\P and \fI--key\fP to specify | ||||
| them independently. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "--cert-type <type>" | ||||
| (SSL) Tells curl what certificate type the provided certificate is in. PEM, | ||||
| DER and ENG are recognized types. | ||||
| DER and ENG are recognized types.  If not specified, PEM is assumed. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "--cacert <CA certificate>" | ||||
| (HTTPS) Tells curl to use the specified certificate file to verify the | ||||
| (SSL) Tells curl to use the specified certificate file to verify the | ||||
| peer. The file may contain multiple CA certificates. The certificate(s) must | ||||
| be in PEM format. | ||||
|  | ||||
| @@ -344,10 +344,10 @@ Current Working Directory, or in any folder along your PATH. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "--capath <CA certificate directory>" | ||||
| (HTTPS) Tells curl to use the specified certificate directory to verify the | ||||
| (SSL) Tells curl to use the specified certificate directory to verify the | ||||
| peer. The certificates must be in PEM format, and the directory must have been | ||||
| processed using the c_rehash utility supplied with openssl. Using | ||||
| \fI--capath\fP can allow curl to make https connections much more efficiently | ||||
| \fI--capath\fP can allow curl to make SSL-connections much more efficiently | ||||
| than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA | ||||
| certificates. | ||||
|  | ||||
| @@ -359,6 +359,10 @@ normal cases when a HTTP server fails to deliver a document, it returns an | ||||
| HTML document stating so (which often also describes why and more). This flag | ||||
| will prevent curl from outputting that and return error 22. | ||||
|  | ||||
| This method is not fail-safe and there are occasions where non-succesful | ||||
| response codes will slip through, especially when authentication is involved | ||||
| (response codes 401 and 407). | ||||
|  | ||||
| If this option is used twice, the second will again disable silent failure. | ||||
| .IP "--ftp-account [data]" | ||||
| (FTP) When an FTP server asks for "account data" after user name and password | ||||
| @@ -395,7 +399,11 @@ in 7.11.0) | ||||
|  | ||||
| If this option is used several times, the following occurrences make no | ||||
| difference. | ||||
|  | ||||
| .IP "--ftp-alternative-to-user <command>" | ||||
| (FTP) If authenticating with the USER and PASS commands fails, send this | ||||
| command.  When connecting to Tumbleweed's Secure Transport server over FTPS | ||||
| using a client certificate, using "SITE AUTH" will tell the server to retrieve | ||||
| the username from the certificate. (Added in 7.15.5) | ||||
| .IP "--ftp-skip-pasv-ip" | ||||
| (FTP) Tell curl to not use the IP address the server suggests in its response | ||||
| to curl's PASV command when curl connects the data connection. Instead curl | ||||
| @@ -407,7 +415,22 @@ This option has no effect if PORT, EPRT or EPSV is used instead of PASV. | ||||
| If this option is used twice, the second will again use the server's suggested | ||||
| address. | ||||
| .IP "--ftp-ssl" | ||||
| (FTP) Make the FTP connection switch to use SSL/TLS. (Added in 7.11.0) | ||||
| (FTP) Try to use SSL/TLS for the FTP connection.  Reverts to a non-secure | ||||
| connection if the server doesn't support SSL/TLS.  See also | ||||
| \fI--ftp-ssl-control\fP and \fI--ftp-ssl-reqd\fP for different levels of | ||||
| encryption required. (Added in 7.11.0) | ||||
|  | ||||
| If this option is used twice, the second will again disable this. | ||||
| .IP "--ftp-ssl-control" | ||||
| (FTP) Require SSL/TLS for the ftp login, clear for transfer.  Allows secure | ||||
| authentication, but non-encrypted data transfers for efficiency.  Fails the | ||||
| transfer if the server doesn't support SSL/TLS.  (Added in 7.16.0) | ||||
|  | ||||
| If this option is used twice, the second will again disable this. | ||||
| .IP "--ftp-ssl-reqd" | ||||
| (FTP) Require SSL/TLS for the FTP connection. | ||||
| Terminates the connection if the server doesn't support SSL/TLS. | ||||
| (Added in 7.15.5) | ||||
|  | ||||
| If this option is used twice, the second will again disable this. | ||||
| .IP "-F/--form <name=content>" | ||||
| @@ -476,9 +499,9 @@ of extra headers. Note that if you should add a custom header that has the | ||||
| same name as one of the internal ones curl would use, your externally set | ||||
| 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. Replacing an | ||||
| internal header with one without content on the right side of the colon will | ||||
| prevent that header from appearing. | ||||
| 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:". | ||||
|  | ||||
| curl will make sure that each header you add/replace get sent with the proper | ||||
| end of line marker, you should thus \fBnot\fP add that as a part of the header | ||||
| @@ -527,6 +550,9 @@ and transfers. All SSL connections are attempted to be made secure by using | ||||
| the CA certificate bundle installed by default. This makes all connections | ||||
| considered "insecure" to fail unless \fI-k/--insecure\fP is used. | ||||
|  | ||||
| See this online resource for further details: | ||||
| \fBhttp://curl.haxx.se/docs/sslcerts.html\fP | ||||
|  | ||||
| If this option is used twice, the second time will again disable it. | ||||
| .IP "--key <key>" | ||||
| (SSL) Private key file name. Allows you to provide your private key in this | ||||
| @@ -535,7 +561,8 @@ separate file. | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "--key-type <type>" | ||||
| (SSL) Private key file type. Specify which type your \fI--key\fP provided | ||||
| private key is. DER, PEM and ENG are supported. | ||||
| private key is. DER, PEM and ENG are supported. If not specified, PEM is | ||||
| assumed. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "--krb4 <level>" | ||||
| @@ -692,6 +719,15 @@ will output the data in chunks, not necessarily exactly when the data arrives. | ||||
| Using this option will disable that buffering. | ||||
|  | ||||
| If this option is used twice, the second will again switch on buffering. | ||||
| .IP "--no-sessionid" | ||||
| (SSL) Disable curl's use of SSL session-ID caching.  By default all transfers | ||||
| are done using the cache. Note that while nothing ever should get hurt by | ||||
| attempting to reuse SSL session-IDs, there seem to be broken SSL | ||||
| implementations in the wild that may require you to disable this in order for | ||||
| you to succeed. (Added in 7.16.0) | ||||
|  | ||||
| If this option is used twice, the second will again switch on use of the | ||||
| session cache. | ||||
| .IP "--ntlm" | ||||
| (HTTP) Enables NTLM authentication. The NTLM authentication method was | ||||
| designed by Microsoft and is used by IIS web servers. It is a proprietary | ||||
| @@ -805,7 +841,7 @@ must send syntactically correct FTP commands as RFC959 defines. | ||||
|  | ||||
| This option can be used multiple times. | ||||
| .IP "--random-file <file>" | ||||
| (HTTPS) Specify the path name to file containing what will be considered as | ||||
| (SSL) Specify the path name to file containing what will be considered as | ||||
| random data. The data is used to seed the random engine for SSL connections. | ||||
| See also the \fI--egd-file\fP option. | ||||
| .IP "-r/--range <range>" | ||||
| @@ -1183,7 +1219,7 @@ not set. | ||||
|  | ||||
| If this option is used several times, the last one will be used. | ||||
| .IP "-z/--time-cond <date expression>" | ||||
| (HTTP) Request a file that has been modified later than the given time and | ||||
| (HTTP/FTP) Request a file that has been modified later than the given time and | ||||
| date, or one that has been modified before that time. The date expression can | ||||
| be all sorts of date strings or if it doesn't match any internal ones, it | ||||
| tries to get the time from a given file name instead! See the | ||||
| @@ -1205,25 +1241,14 @@ If this option is used several times, the last one will be used. | ||||
| (HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its | ||||
| internally preferred: HTTP 1.1. | ||||
| .IP "-1/--tlsv1" | ||||
| (HTTPS) | ||||
| (SSL) | ||||
| Forces curl to use TSL version 1 when negotiating with a remote TLS server. | ||||
| .IP "-2/--sslv2" | ||||
| (HTTPS) | ||||
| (SSL) | ||||
| Forces curl to use SSL version 2 when negotiating with a remote SSL server. | ||||
| .IP "-3/--sslv3" | ||||
| (HTTPS) | ||||
| (SSL) | ||||
| Forces curl to use SSL version 3 when negotiating with a remote SSL server. | ||||
| .IP "--3p-quote" | ||||
| (FTP) Specify arbitrary commands to send to the source server. See the | ||||
| \fI-Q/--quote\fP option for details. (Added in 7.13.0) | ||||
| .IP "--3p-url" | ||||
| (FTP) Activates a FTP 3rd party transfer. Specifies the source URL to get a | ||||
| file from, while the "normal" URL will be used as target URL, the file that | ||||
| will be written/created. | ||||
|  | ||||
| Note that not all FTP server allow 3rd party transfers. (Added in 7.13.0) | ||||
| .IP "--3p-user" | ||||
| (FTP) Specify user:password for the source URL transfer. (Added in 7.13.0) | ||||
| .IP "-4/--ipv4" | ||||
| If libcurl is capable of resolving an address to multiple IP versions (which | ||||
| it is if it is ipv6-capable), this option tells libcurl to resolve names to | ||||
| @@ -1240,7 +1265,7 @@ If this option is used twice, the second will again disable the progress bar. | ||||
| .SH FILES | ||||
| .I ~/.curlrc | ||||
| .RS | ||||
| Default config file. | ||||
| Default config file, see \fI-K/--config\fP for details. | ||||
|  | ||||
| .SH ENVIRONMENT | ||||
| .IP "http_proxy [protocol://]<host>[:port]" | ||||
|   | ||||
							
								
								
									
										166
									
								
								docs/examples/10-at-a-time.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								docs/examples/10-at-a-time.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  * | ||||
|  * Example application source code using the multi interface to download many | ||||
|  * files, but with a capped maximum amount of simultaneous transfers. | ||||
|  * | ||||
|  * Written by Michael Wallner | ||||
|  */ | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <curl/multi.h> | ||||
|  | ||||
| static const char *urls[] = { | ||||
|   "http://www.microsoft.com", | ||||
|   "http://www.opensource.org", | ||||
|   "http://www.google.com", | ||||
|   "http://www.yahoo.com", | ||||
|   "http://www.ibm.com", | ||||
|   "http://www.mysql.com", | ||||
|   "http://www.oracle.com", | ||||
|   "http://www.ripe.net", | ||||
|   "http://www.iana.org", | ||||
|   "http://www.amazon.com", | ||||
|   "http://www.netcraft.com", | ||||
|   "http://www.heise.de", | ||||
|   "http://www.chip.de", | ||||
|   "http://www.ca.com", | ||||
|   "http://www.cnet.com", | ||||
|   "http://www.news.com", | ||||
|   "http://www.cnn.com", | ||||
|   "http://www.wikipedia.org", | ||||
|   "http://www.dell.com", | ||||
|   "http://www.hp.com", | ||||
|   "http://www.cert.org", | ||||
|   "http://www.mit.edu", | ||||
|   "http://www.nist.gov", | ||||
|   "http://www.ebay.com", | ||||
|   "http://www.playstation.com", | ||||
|   "http://www.uefa.com", | ||||
|   "http://www.ieee.org", | ||||
|   "http://www.apple.com", | ||||
|   "http://www.sony.com", | ||||
|   "http://www.symantec.com", | ||||
|   "http://www.zdnet.com", | ||||
|   "http://www.fujitsu.com", | ||||
|   "http://www.supermicro.com", | ||||
|   "http://www.hotmail.com", | ||||
|   "http://www.ecma.com", | ||||
|   "http://www.bbc.co.uk", | ||||
|   "http://news.google.com", | ||||
|   "http://www.foxnews.com", | ||||
|   "http://www.msn.com", | ||||
|   "http://www.wired.com", | ||||
|   "http://www.sky.com", | ||||
|   "http://www.usatoday.com", | ||||
|   "http://www.cbs.com", | ||||
|   "http://www.nbc.com", | ||||
|   "http://slashdot.org", | ||||
|   "http://www.bloglines.com", | ||||
|   "http://www.techweb.com", | ||||
|   "http://www.newslink.org", | ||||
|   "http://www.un.org", | ||||
| }; | ||||
|  | ||||
| #define MAX 10 /* number of simultaneous transfers */ | ||||
| #define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */ | ||||
|  | ||||
| static int cb(char *d, size_t n, size_t l, void *p) | ||||
| { | ||||
|   /* take care of the data here, ignored in this example */ | ||||
|   (void)d; | ||||
|   (void)p; | ||||
|   return n*l; | ||||
| } | ||||
|  | ||||
| static void init(CURLM *cm, int i) | ||||
| { | ||||
|   CURL *eh = curl_easy_init(); | ||||
|  | ||||
|   curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb); | ||||
|   curl_easy_setopt(eh, CURLOPT_HEADER, 0); | ||||
|   curl_easy_setopt(eh, CURLOPT_URL, urls[i]); | ||||
|   curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]); | ||||
|   curl_easy_setopt(eh, CURLOPT_VERBOSE, 0); | ||||
|  | ||||
|   curl_multi_add_handle(cm, eh); | ||||
| } | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   CURLM *cm; | ||||
|   CURLMsg *msg; | ||||
|   long L; | ||||
|   unsigned int C=0; | ||||
|   int M, Q, U = -1; | ||||
|   fd_set R, W, E; | ||||
|   struct timeval T; | ||||
|  | ||||
|   curl_global_init(CURL_GLOBAL_ALL); | ||||
|  | ||||
|   cm = curl_multi_init(); | ||||
|  | ||||
|   for (C = 0; C < MAX; ++C) { | ||||
|     init(cm, C); | ||||
|   } | ||||
|  | ||||
|   while (U) { | ||||
|     while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(cm, &U)); | ||||
|  | ||||
|     if (U) { | ||||
|       FD_ZERO(&R); | ||||
|       FD_ZERO(&W); | ||||
|       FD_ZERO(&E); | ||||
|  | ||||
|       if (curl_multi_fdset(cm, &R, &W, &E, &M)) { | ||||
|         fprintf(stderr, "E: curl_multi_fdset\n"); | ||||
|         return EXIT_FAILURE; | ||||
|       } | ||||
|  | ||||
|       /* In a real-world program you OF COURSE check the return that maxfd is | ||||
|          bigger than -1 so that the call to select() below makes sense! */ | ||||
|  | ||||
|       if (curl_multi_timeout(cm, &L)) { | ||||
|         fprintf(stderr, "E: curl_multi_timeout\n"); | ||||
|         return EXIT_FAILURE; | ||||
|       } | ||||
|  | ||||
|       T.tv_sec = L/1000; | ||||
|       T.tv_usec = (L%1000)*1000; | ||||
|  | ||||
|       if (0 > select(M+1, &R, &W, &E, &T)) { | ||||
|         fprintf(stderr, "E: select\n"); | ||||
|         return EXIT_FAILURE; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     while ((msg = curl_multi_info_read(cm, &Q))) { | ||||
|       if (msg->msg == CURLMSG_DONE) { | ||||
|         char *url; | ||||
|         CURL *e = msg->easy_handle; | ||||
|         curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url); | ||||
|         fprintf(stderr, "R: %d - %s <%s>\n", | ||||
|                 msg->data.result, curl_easy_strerror(msg->data.result), url); | ||||
|         curl_multi_remove_handle(cm, e); | ||||
|         curl_easy_cleanup(e); | ||||
|       } | ||||
|       else { | ||||
|         fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg); | ||||
|       } | ||||
|       if (C < CNT) { | ||||
|         init(cm, C++); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   curl_multi_cleanup(cm); | ||||
|   curl_global_cleanup(); | ||||
|  | ||||
|   return EXIT_SUCCESS; | ||||
| } | ||||
| @@ -11,7 +11,8 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c		\ | ||||
|  multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c		\ | ||||
|  multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c	\ | ||||
|  anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c		\ | ||||
|  cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c | ||||
|  cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c \ | ||||
|  10-at-a-time.c hiperfifo.c ghiper.c | ||||
|  | ||||
| all: | ||||
| 	@echo "done" | ||||
|   | ||||
| @@ -26,9 +26,9 @@ want you do reorganize them like: | ||||
|   $ `curl-config --cc` -o example example.c `curl-config --cflags --libs` | ||||
|  | ||||
| *PLEASE* do not use the curl.haxx.se site as a test target for your libcurl | ||||
| applications/experiments. Even if the examples in this directory use that site | ||||
| as an example URL at some places, it doesn't mean that the URLs work or that | ||||
| we expect you to actually torture our web site with your tests! Thanks. | ||||
| applications/experiments. Even if some of the examples use that site as a URL | ||||
| at some places, it doesn't mean that the URLs work or that we expect you to | ||||
| actually torture our web site with your tests!  Thanks. | ||||
|  | ||||
| EXAMPLES | ||||
|  | ||||
| @@ -43,9 +43,13 @@ fopen.c        - fopen() layer that supports opening URLs and files | ||||
| ftp3rdparty.c  - FTP 3rd party transfer | ||||
| ftpget.c       - simple getting a file from FTP | ||||
| ftpgetresp.c   - get the response strings from the FTP server | ||||
| ftpupload.c    - upload a file to a FTP server | ||||
| ftpupload.c    - upload a file to an FTP server | ||||
| ftpuploadresume.c - resume an upload to an FTP server | ||||
| getinfo.c      - get the Content-Type from the recent transfer | ||||
| getinmemory.c  - download a file to memory only | ||||
| ghiper.c       - curl_multi_socket() using code with glib-2 | ||||
| hiperfifo.c    - downloads all URLs written to the fifo, using | ||||
|                  curl_multi_socket() and libevent | ||||
| htmltitle.cc   - download a HTML file and extract the <title> tag from a HTML | ||||
|                  page using libxml | ||||
| http-post.c    - HTTP POST | ||||
| @@ -61,8 +65,12 @@ opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded | ||||
| persistant.c   - request two URLs with a persistant connection | ||||
| 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 | ||||
|                  callbacks to do its own codeset conversions instead of using | ||||
|                  the built-in iconv functions in libcurl | ||||
| sepheaders.c   - download headers to a separate file | ||||
| 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 extracing date from remote HTTP servers | ||||
| 10-at-a-time.c - Download many files simultaneously, 10 at a time. | ||||
|   | ||||
| @@ -114,6 +114,13 @@ static char *curlx_usage[]={ | ||||
|  | ||||
| */ | ||||
|  | ||||
| /*  | ||||
|  * We use this ZERO_NULL to avoid picky compiler warnings, | ||||
|  * when assigning a NULL pointer to a function pointer var. | ||||
|  */ | ||||
|  | ||||
| #define ZERO_NULL 0 | ||||
|  | ||||
| /* This is a context that we pass to all callbacks */ | ||||
|  | ||||
| typedef struct sslctxparm_st { | ||||
| @@ -236,7 +243,7 @@ static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) { | ||||
|  | ||||
|   SSL_CTX_set_verify_depth(ctx,2); | ||||
|  | ||||
|   SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); | ||||
|   SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL); | ||||
|  | ||||
|   SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm); | ||||
|  | ||||
|   | ||||
| @@ -84,6 +84,9 @@ int my_trace(CURL *handle, curl_infotype type, | ||||
|   case CURLINFO_DATA_OUT: | ||||
|     text = "=> Send data"; | ||||
|     break; | ||||
|   case CURLINFO_SSL_DATA_OUT: | ||||
|     text = "=> Send SSL data"; | ||||
|     break; | ||||
|   case CURLINFO_HEADER_IN: | ||||
|     text = "<= Recv header"; | ||||
|     break; | ||||
| @@ -93,9 +96,6 @@ int my_trace(CURL *handle, curl_infotype type, | ||||
|   case CURLINFO_SSL_DATA_IN: | ||||
|     text = "<= Recv SSL data"; | ||||
|     break; | ||||
|   case CURLINFO_SSL_DATA_OUT: | ||||
|     text = "<= Send SSL data"; | ||||
|     break; | ||||
|   } | ||||
|  | ||||
|   dump(text, stderr, data, size, config->trace_ascii); | ||||
|   | ||||
| @@ -153,6 +153,10 @@ fill_buffer(URL_FILE *file,int want,int waittime) | ||||
|         /* get file descriptors from the transfers */ | ||||
|         curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||
|  | ||||
|         /* In a real-world program you OF COURSE check the return code of the | ||||
|            function calls, *and* you make sure that maxfd is bigger than -1 | ||||
|            so that the call to select() below makes sense! */ | ||||
|  | ||||
|         rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||
|  | ||||
|         switch(rc) { | ||||
|   | ||||
							
								
								
									
										461
									
								
								docs/examples/ghiper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										461
									
								
								docs/examples/ghiper.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,461 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  * | ||||
|  * Example application source code using the multi socket interface to | ||||
|  * download many files at once. | ||||
|  * | ||||
|  * Written by Jeff Pohlmeyer | ||||
|  | ||||
| Requires glib-2.x and a (POSIX?) system that has mkfifo(). | ||||
|  | ||||
| This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" | ||||
| sample programs, adapted to use glib's g_io_channel in place of libevent. | ||||
|  | ||||
| When running, the program creates the named pipe "hiper.fifo" | ||||
|  | ||||
| Whenever there is input into the fifo, the program reads the input as a list | ||||
| of URL's and creates some new easy handles to fetch each URL via the | ||||
| curl_multi "hiper" API. | ||||
|  | ||||
|  | ||||
| Thus, you can try a single URL: | ||||
|   % echo http://www.yahoo.com > hiper.fifo | ||||
|  | ||||
| Or a whole bunch of them: | ||||
|   % cat my-url-list > hiper.fifo | ||||
|  | ||||
| The fifo buffer is handled almost instantly, so you can even add more URL's | ||||
| while the previous requests are still being downloaded. | ||||
|  | ||||
| This is purely a demo app, all retrieved data is simply discarded by the write | ||||
| callback. | ||||
|  | ||||
| */ | ||||
|  | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include <curl/curl.h> | ||||
|  | ||||
|  | ||||
| #define MSG_OUT g_print   /* Change to "g_error" to write to stderr */ | ||||
| #define SHOW_VERBOSE 0    /* Set to non-zero for libcurl messages */ | ||||
| #define SHOW_PROGRESS 0   /* Set to non-zero to enable progress callback */ | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Global information, common to all connections */ | ||||
| typedef struct _GlobalInfo { | ||||
|   CURLM *multi; | ||||
|   guint timer_event; | ||||
|   int prev_running; | ||||
|   int still_running; | ||||
|   int requested; /* count: curl_easy_init() */ | ||||
|   int completed; /* count: curl_easy_cleanup() */ | ||||
| } GlobalInfo; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Information associated with a specific easy handle */ | ||||
| typedef struct _ConnInfo { | ||||
|   CURL *easy; | ||||
|   char *url; | ||||
|   GlobalInfo *global; | ||||
|   char error[CURL_ERROR_SIZE]; | ||||
| } ConnInfo; | ||||
|  | ||||
|  | ||||
| /* Information associated with a specific socket */ | ||||
| typedef struct _SockInfo { | ||||
|   curl_socket_t sockfd; | ||||
|   CURL *easy; | ||||
|   int action; | ||||
|   long timeout; | ||||
|   GIOChannel *ch; | ||||
|   guint ev; | ||||
|   GlobalInfo *global; | ||||
| } SockInfo; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Die if we get a bad CURLMcode somewhere */ | ||||
| static void mcode_or_die(char *where, CURLMcode code) { | ||||
|   if ( CURLM_OK != code ) { | ||||
|     char *s; | ||||
|     switch (code) { | ||||
|       case     CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break; | ||||
|       case     CURLM_OK:                 s="CURLM_OK";                 break; | ||||
|       case     CURLM_BAD_HANDLE:         s="CURLM_BAD_HANDLE";         break; | ||||
|       case     CURLM_BAD_EASY_HANDLE:    s="CURLM_BAD_EASY_HANDLE";    break; | ||||
|       case     CURLM_OUT_OF_MEMORY:      s="CURLM_OUT_OF_MEMORY";      break; | ||||
|       case     CURLM_INTERNAL_ERROR:     s="CURLM_INTERNAL_ERROR";     break; | ||||
|       case     CURLM_BAD_SOCKET:         s="CURLM_BAD_SOCKET";         break; | ||||
|       case     CURLM_UNKNOWN_OPTION:     s="CURLM_UNKNOWN_OPTION";     break; | ||||
|       case     CURLM_LAST:               s="CURLM_LAST";               break; | ||||
|       default: s="CURLM_unknown"; | ||||
|     } | ||||
|     MSG_OUT("ERROR: %s returns %s\n", where, s); | ||||
|     exit(code); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Check for completed transfers, and remove their easy handles */ | ||||
| static void check_run_count(GlobalInfo *g) | ||||
| { | ||||
|   if (g->prev_running > g->still_running) { | ||||
|     char *eff_url=NULL; | ||||
|     CURLMsg *msg; | ||||
|     int msgs_left; | ||||
|     ConnInfo *conn=NULL; | ||||
|     CURL*easy; | ||||
|     CURLcode res; | ||||
|  | ||||
|     MSG_OUT("REMAINING: %d\n", g->still_running); | ||||
|     /* | ||||
|       I am still uncertain whether it is safe to remove an easy handle | ||||
|       from inside the curl_multi_info_read loop, so here I will search | ||||
|       for completed transfers in the inner "while" loop, and then remove | ||||
|       them in the outer "do-while" loop... | ||||
|    */ | ||||
|     do { | ||||
|       easy=NULL; | ||||
|       while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { | ||||
|         if (msg->msg == CURLMSG_DONE) { | ||||
|           easy=msg->easy_handle; | ||||
|           res=msg->data.result; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       if (easy) { | ||||
|           curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); | ||||
|           curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); | ||||
|           MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error); | ||||
|           curl_multi_remove_handle(g->multi, easy); | ||||
|           g_free(conn->url); | ||||
|           curl_easy_cleanup(easy); | ||||
|           g_free(conn); | ||||
|           g->completed++; | ||||
|       } | ||||
|     } while ( easy ); | ||||
|     MSG_OUT("Requested: %d Completed:%d\n", g->requested, g->completed); | ||||
|   } | ||||
|   g->prev_running = g->still_running; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Called by glib when our timeout expires */ | ||||
| static gboolean timer_cb(gpointer data) | ||||
| { | ||||
|   GlobalInfo *g = (GlobalInfo *)data; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   do { | ||||
|     rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running); | ||||
|   } while (rc == CURLM_CALL_MULTI_PERFORM); | ||||
|   mcode_or_die("timer_cb: curl_multi_socket", rc); | ||||
|   check_run_count(g); | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Update the event timer after curl_multi library calls */ | ||||
| static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp) | ||||
| { | ||||
|   struct timeval timeout; | ||||
|   GlobalInfo *g=(GlobalInfo *)userp; | ||||
|   timeout.tv_sec = timeout_ms/1000; | ||||
|   timeout.tv_usec = (timeout_ms%1000)*1000; | ||||
|  | ||||
|   MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n", | ||||
|               timeout_ms, timeout.tv_sec, timeout.tv_usec); | ||||
|  | ||||
|   g->timer_event = g_timeout_add(timeout_ms, timer_cb, g); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Called by glib when we get action on a multi socket */ | ||||
| static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) | ||||
| { | ||||
|   GlobalInfo *g = (GlobalInfo*) data; | ||||
|   CURLMcode rc; | ||||
|   int fd=g_io_channel_unix_get_fd(ch); | ||||
|   do { | ||||
|     rc = curl_multi_socket(g->multi, fd, &g->still_running); | ||||
|   } while (rc == CURLM_CALL_MULTI_PERFORM); | ||||
|   mcode_or_die("event_cb: curl_multi_socket", rc); | ||||
|   check_run_count(g); | ||||
|   if(g->still_running) { | ||||
|     return TRUE; | ||||
|   } else { | ||||
|     MSG_OUT("last transfer done, kill timeout\n"); | ||||
|     if (g->timer_event) { g_source_remove(g->timer_event); } | ||||
|     return FALSE; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Clean up the SockInfo structure */ | ||||
| static void remsock(SockInfo *f) | ||||
| { | ||||
|   if (!f) { return; } | ||||
|   if (f->ev) { g_source_remove(f->ev); } | ||||
|   g_free(f); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Assign information to a SockInfo structure */ | ||||
| static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g) | ||||
| { | ||||
|   GIOCondition kind = | ||||
|      (act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0); | ||||
|  | ||||
|   f->sockfd = s; | ||||
|   f->action = act; | ||||
|   f->easy = e; | ||||
|   if (f->ev) { g_source_remove(f->ev); } | ||||
|   f->ev=g_io_add_watch(f->ch, kind, event_cb,g); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Initialize a new SockInfo structure */ | ||||
| static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) | ||||
| { | ||||
|   SockInfo *fdp = g_malloc0(sizeof(SockInfo)); | ||||
|  | ||||
|   fdp->global = g; | ||||
|   fdp->ch=g_io_channel_unix_new(s); | ||||
|   setsock(fdp, s, easy, action, g); | ||||
|   curl_multi_assign(g->multi, s, fdp); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* CURLMOPT_SOCKETFUNCTION */ | ||||
| static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) | ||||
| { | ||||
|   GlobalInfo *g = (GlobalInfo*) cbp; | ||||
|   SockInfo *fdp = (SockInfo*) sockp; | ||||
|   char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; | ||||
|  | ||||
|   MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); | ||||
|   if (what == CURL_POLL_REMOVE) { | ||||
|     MSG_OUT("\n"); | ||||
|     remsock(fdp); | ||||
|   } else { | ||||
|     if (!fdp) { | ||||
|       MSG_OUT("Adding data: %s%s\n", | ||||
|              what&CURL_POLL_IN?"READ":"", | ||||
|              what&CURL_POLL_OUT?"WRITE":"" ); | ||||
|       addsock(s, e, what, g); | ||||
|     } | ||||
|     else { | ||||
|       MSG_OUT( | ||||
|         "Changing action from %d to %d\n", fdp->action, what); | ||||
|       setsock(fdp, s, e, what, g); | ||||
|     } | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* CURLOPT_WRITEFUNCTION */ | ||||
| static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) | ||||
| { | ||||
|   size_t realsize = size * nmemb; | ||||
|   ConnInfo *conn = (ConnInfo*) data; | ||||
|   (void)ptr; | ||||
|   (void)conn; | ||||
|   return realsize; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* CURLOPT_PROGRESSFUNCTION */ | ||||
| static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln) | ||||
| { | ||||
|   ConnInfo *conn = (ConnInfo *)p; | ||||
|   MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Create a new easy handle, and add it to the global curl_multi */ | ||||
| static void new_conn(char *url, GlobalInfo *g ) | ||||
| { | ||||
|   ConnInfo *conn; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   conn = g_malloc0(sizeof(ConnInfo)); | ||||
|  | ||||
|   conn->error[0]='\0'; | ||||
|  | ||||
|   conn->easy = curl_easy_init(); | ||||
|   if (!conn->easy) { | ||||
|     MSG_OUT("curl_easy_init() failed, exiting!\n"); | ||||
|     exit(2); | ||||
|   } | ||||
|   conn->global = g; | ||||
|   conn->url = g_strdup(url); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, SHOW_VERBOSE); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0:1); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30); | ||||
|  | ||||
|   MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); | ||||
|   rc =curl_multi_add_handle(g->multi, conn->easy); | ||||
|   mcode_or_die("new_conn: curl_multi_add_handle", rc); | ||||
|   g->requested++; | ||||
|   do { | ||||
|     rc = curl_multi_socket_all(g->multi, &g->still_running); | ||||
|   } while (CURLM_CALL_MULTI_PERFORM == rc); | ||||
|   mcode_or_die("new_conn: curl_multi_socket_all", rc); | ||||
|   check_run_count(g); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This gets called by glib whenever data is received from the fifo */ | ||||
| static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data) | ||||
| { | ||||
|   #define BUF_SIZE 1024 | ||||
|   gsize len, tp; | ||||
|   gchar *buf, *tmp, *all=NULL; | ||||
|   GIOStatus rv; | ||||
|  | ||||
|   do { | ||||
|     GError *err=NULL; | ||||
|     rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err); | ||||
|     if ( buf ) { | ||||
|       if (tp) { buf[tp]='\0'; } | ||||
|       new_conn(buf,(GlobalInfo*)data); | ||||
|       g_free(buf); | ||||
|     } else { | ||||
|       buf = g_malloc(BUF_SIZE+1); | ||||
|       while (TRUE) { | ||||
|         buf[BUF_SIZE]='\0'; | ||||
|         g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err); | ||||
|         if (len) { | ||||
|           buf[len]='\0'; | ||||
|           if (all) { | ||||
|             tmp=all; | ||||
|             all=g_strdup_printf("%s%s", tmp, buf); | ||||
|             g_free(tmp); | ||||
|           } else { | ||||
|             all = g_strdup(buf); | ||||
|           } | ||||
|         } else { | ||||
|            break; | ||||
|         } | ||||
|       } | ||||
|       if (all) { | ||||
|         new_conn(all,(GlobalInfo*)data); | ||||
|         g_free(all); | ||||
|       } | ||||
|       g_free(buf); | ||||
|     } | ||||
|     if ( err ) { | ||||
|       g_error("fifo_cb: %s", err->message); | ||||
|       g_free(err); | ||||
|       break; | ||||
|     } | ||||
|   } while ( (len) && (rv == G_IO_STATUS_NORMAL) ); | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int init_fifo(void) | ||||
| { | ||||
|  struct stat st; | ||||
|  char *fifo = "hiper.fifo"; | ||||
|  int socket; | ||||
|  | ||||
|  if (lstat (fifo, &st) == 0) { | ||||
|   if ((st.st_mode & S_IFMT) == S_IFREG) { | ||||
|    errno = EEXIST; | ||||
|    perror("lstat"); | ||||
|    exit (1); | ||||
|   } | ||||
|  } | ||||
|  | ||||
|  unlink (fifo); | ||||
|  if (mkfifo (fifo, 0600) == -1) { | ||||
|   perror("mkfifo"); | ||||
|   exit (1); | ||||
|  } | ||||
|  | ||||
|  socket = open (fifo, O_RDWR | O_NONBLOCK, 0); | ||||
|  | ||||
|  if (socket == -1) { | ||||
|   perror("open"); | ||||
|   exit (1); | ||||
|  } | ||||
|  MSG_OUT("Now, pipe some URL's into > %s\n", fifo); | ||||
|  | ||||
|  return socket; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|   GlobalInfo *g; | ||||
|   CURLMcode rc; | ||||
|   GMainLoop*gmain; | ||||
|   int fd; | ||||
|   GIOChannel* ch; | ||||
|   g=g_malloc0(sizeof(GlobalInfo)); | ||||
|  | ||||
|   fd=init_fifo(); | ||||
|   ch=g_io_channel_unix_new(fd); | ||||
|   g_io_add_watch(ch,G_IO_IN,fifo_cb,g); | ||||
|   gmain=g_main_loop_new(NULL,FALSE); | ||||
|   g->multi = curl_multi_init(); | ||||
|   curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb); | ||||
|   curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g); | ||||
|   curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb); | ||||
|   curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g); | ||||
|   do { | ||||
|     rc = curl_multi_socket_all(g->multi, &g->still_running); | ||||
|   } while (CURLM_CALL_MULTI_PERFORM == rc); | ||||
|   g_main_loop_run(gmain); | ||||
|   curl_multi_cleanup(g->multi); | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										416
									
								
								docs/examples/hiperfifo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								docs/examples/hiperfifo.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,416 @@ | ||||
| /***************************************************************************** | ||||
|  *                                  _   _ ____  _ | ||||
|  *  Project                     ___| | | |  _ \| | | ||||
|  *                             / __| | | | |_) | | | ||||
|  *                            | (__| |_| |  _ <| |___ | ||||
|  *                             \___|\___/|_| \_\_____| | ||||
|  * | ||||
|  * $Id$ | ||||
|  * | ||||
|  * Example application source code using the multi socket interface to | ||||
|  * download many files at once. | ||||
|  * | ||||
|  * Written by Jeff Pohlmeyer | ||||
|  | ||||
| Requires libevent and a (POSIX?) system that has mkfifo(). | ||||
|  | ||||
| This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" | ||||
| sample programs. | ||||
|  | ||||
| When running, the program creates the named pipe "hiper.fifo" | ||||
|  | ||||
| Whenever there is input into the fifo, the program reads the input as a list | ||||
| of URL's and creates some new easy handles to fetch each URL via the | ||||
| curl_multi "hiper" API. | ||||
|  | ||||
|  | ||||
| Thus, you can try a single URL: | ||||
|   % echo http://www.yahoo.com > hiper.fifo | ||||
|  | ||||
| Or a whole bunch of them: | ||||
|   % cat my-url-list > hiper.fifo | ||||
|  | ||||
| The fifo buffer is handled almost instantly, so you can even add more URL's | ||||
| while the previous requests are still being downloaded. | ||||
|  | ||||
| Note: | ||||
|   For the sake of simplicity, URL length is limited to 1023 char's ! | ||||
|  | ||||
| This is purely a demo app, all retrieved data is simply discarded by the write | ||||
| callback. | ||||
|  | ||||
| */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/poll.h> | ||||
| #include <curl/curl.h> | ||||
| #include <event.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/stat.h> | ||||
| #include <errno.h> | ||||
|  | ||||
|  | ||||
| #define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */ | ||||
|  | ||||
|  | ||||
| /* Global information, common to all connections */ | ||||
| typedef struct _GlobalInfo { | ||||
|   struct event fifo_event; | ||||
|   struct event timer_event; | ||||
|   CURLM *multi; | ||||
|   int prev_running; | ||||
|   int still_running; | ||||
|   FILE* input; | ||||
| } GlobalInfo; | ||||
|  | ||||
|  | ||||
| /* Information associated with a specific easy handle */ | ||||
| typedef struct _ConnInfo { | ||||
|   CURL *easy; | ||||
|   char *url; | ||||
|   GlobalInfo *global; | ||||
|   char error[CURL_ERROR_SIZE]; | ||||
| } ConnInfo; | ||||
|  | ||||
|  | ||||
| /* Information associated with a specific socket */ | ||||
| typedef struct _SockInfo { | ||||
|   curl_socket_t sockfd; | ||||
|   CURL *easy; | ||||
|   int action; | ||||
|   long timeout; | ||||
|   struct event ev; | ||||
|   int evset; | ||||
|   GlobalInfo *global; | ||||
| } SockInfo; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Update the event timer after curl_multi library calls */ | ||||
| static void update_timeout(GlobalInfo *g) | ||||
| { | ||||
|   long timeout_ms; | ||||
|   struct timeval timeout; | ||||
|  | ||||
|   curl_multi_timeout(g->multi, &timeout_ms); | ||||
|   if(timeout_ms < 0) | ||||
|     return; | ||||
|  | ||||
|   timeout.tv_sec = timeout_ms/1000; | ||||
|   timeout.tv_usec = (timeout_ms%1000)*1000; | ||||
|   evtimer_add(&g->timer_event, &timeout); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Die if we get a bad CURLMcode somewhere */ | ||||
| void mcode_or_die(char *where, CURLMcode code) { | ||||
|   if ( CURLM_OK != code ) { | ||||
|     char *s; | ||||
|     switch (code) { | ||||
|       case     CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break; | ||||
|       case     CURLM_OK:                 s="CURLM_OK";                 break; | ||||
|       case     CURLM_BAD_HANDLE:         s="CURLM_BAD_HANDLE";         break; | ||||
|       case     CURLM_BAD_EASY_HANDLE:    s="CURLM_BAD_EASY_HANDLE";    break; | ||||
|       case     CURLM_OUT_OF_MEMORY:      s="CURLM_OUT_OF_MEMORY";      break; | ||||
|       case     CURLM_INTERNAL_ERROR:     s="CURLM_INTERNAL_ERROR";     break; | ||||
|       case     CURLM_BAD_SOCKET:         s="CURLM_BAD_SOCKET";         break; | ||||
|       case     CURLM_UNKNOWN_OPTION:     s="CURLM_UNKNOWN_OPTION";     break; | ||||
|       case     CURLM_LAST:               s="CURLM_LAST";               break; | ||||
|       default: s="CURLM_unknown"; | ||||
|     } | ||||
|     fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); | ||||
|     exit(code); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Check for completed transfers, and remove their easy handles */ | ||||
| static void check_run_count(GlobalInfo *g) | ||||
| { | ||||
|   if (g->prev_running > g->still_running) { | ||||
|     char *eff_url=NULL; | ||||
|     CURLMsg *msg; | ||||
|     int msgs_left; | ||||
|     ConnInfo *conn=NULL; | ||||
|     CURL*easy; | ||||
|     CURLcode res; | ||||
|  | ||||
|     fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running); | ||||
|     /* | ||||
|       I am still uncertain whether it is safe to remove an easy handle | ||||
|       from inside the curl_multi_info_read loop, so here I will search | ||||
|       for completed transfers in the inner "while" loop, and then remove | ||||
|       them in the outer "do-while" loop... | ||||
|    */ | ||||
|     do { | ||||
|       easy=NULL; | ||||
|       while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { | ||||
|         if (msg->msg == CURLMSG_DONE) { | ||||
|           easy=msg->easy_handle; | ||||
|           res=msg->data.result; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       if (easy) { | ||||
|           curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); | ||||
|           curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); | ||||
|           fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error); | ||||
|           curl_multi_remove_handle(g->multi, easy); | ||||
|           free(conn->url); | ||||
|           curl_easy_cleanup(easy); | ||||
|           free(conn); | ||||
|       } | ||||
|     } while ( easy ); | ||||
|   } | ||||
|   g->prev_running = g->still_running; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Called by libevent when we get action on a multi socket */ | ||||
| static void event_cb(int fd, short kind, void *userp) | ||||
| { | ||||
|   GlobalInfo *g = (GlobalInfo*) userp; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   do { | ||||
|     rc = curl_multi_socket(g->multi, fd, &g->still_running); | ||||
|   } while (rc == CURLM_CALL_MULTI_PERFORM); | ||||
|   mcode_or_die("event_cb: curl_multi_socket", rc); | ||||
|   check_run_count(g); | ||||
|   if(g->still_running) { | ||||
|     update_timeout(g); | ||||
|   } else { | ||||
|     fprintf(MSG_OUT, "last transfer done, kill timeout\n"); | ||||
|     if (evtimer_pending(&g->timer_event, NULL)) { | ||||
|       evtimer_del(&g->timer_event); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Called by libevent when our timeout expires */ | ||||
| static void timer_cb(int fd, short kind, void *userp) | ||||
| { | ||||
|   (void)fd; | ||||
|   (void)kind; | ||||
|   GlobalInfo *g = (GlobalInfo *)userp; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   do { | ||||
|     rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running); | ||||
|   } while (rc == CURLM_CALL_MULTI_PERFORM); | ||||
|   mcode_or_die("timer_cb: curl_multi_socket", rc); | ||||
|   check_run_count(g); | ||||
|   if ( g->still_running ) { update_timeout(g); } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Clean up the SockInfo structure */ | ||||
| static void remsock(SockInfo *f) | ||||
| { | ||||
|   if (!f) { return; } | ||||
|   if (f->evset) { event_del(&f->ev); } | ||||
|   free(f); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Assign information to a SockInfo structure */ | ||||
| static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g) | ||||
| { | ||||
|   int kind = | ||||
|      (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST; | ||||
|  | ||||
|   f->sockfd = s; | ||||
|   f->action = act; | ||||
|   f->easy = e; | ||||
|   if (f->evset) { event_del(&f->ev); } | ||||
|   event_set( &f->ev, f->sockfd, kind, event_cb, g); | ||||
|   f->evset=1; | ||||
|   event_add(&f->ev, NULL); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Initialize a new SockInfo structure */ | ||||
| static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) { | ||||
|   SockInfo *fdp = calloc(sizeof(SockInfo), 1); | ||||
|  | ||||
|   fdp->global = g; | ||||
|   setsock(fdp, s, easy, action, g); | ||||
|   curl_multi_assign(g->multi, s, fdp); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* CURLMOPT_SOCKETFUNCTION */ | ||||
| static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) | ||||
| { | ||||
|   GlobalInfo *g = (GlobalInfo*) cbp; | ||||
|   SockInfo *fdp = (SockInfo*) sockp; | ||||
|   char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; | ||||
|  | ||||
|   fprintf(MSG_OUT, | ||||
|           "socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); | ||||
|   if (what == CURL_POLL_REMOVE) { | ||||
|     fprintf(MSG_OUT, "\n"); | ||||
|     remsock(fdp); | ||||
|   } else { | ||||
|     if (!fdp) { | ||||
|       fprintf(MSG_OUT, "Adding data: %s%s\n", | ||||
|              what&CURL_POLL_IN?"READ":"", | ||||
|              what&CURL_POLL_OUT?"WRITE":"" ); | ||||
|       addsock(s, e, what, g); | ||||
|     } | ||||
|     else { | ||||
|       fprintf(MSG_OUT, | ||||
|         "Changing action from %d to %d\n", fdp->action, what); | ||||
|       setsock(fdp, s, e, what, g); | ||||
|     } | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* CURLOPT_WRITEFUNCTION */ | ||||
| static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) | ||||
| { | ||||
|   size_t realsize = size * nmemb; | ||||
|   ConnInfo *conn = (ConnInfo*) data; | ||||
|   (void)ptr; | ||||
|   (void)conn; | ||||
|   return realsize; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* CURLOPT_PROGRESSFUNCTION */ | ||||
| int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln) | ||||
| { | ||||
|   ConnInfo *conn = (ConnInfo *)p; | ||||
|   fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Create a new easy handle, and add it to the global curl_multi */ | ||||
| void new_conn(char *url, GlobalInfo *g ) { | ||||
|   ConnInfo *conn; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   conn = calloc(1, sizeof(ConnInfo)); | ||||
|   memset(conn, 0, sizeof(ConnInfo)); | ||||
|   conn->error[0]='\0'; | ||||
|  | ||||
|   conn->easy = curl_easy_init(); | ||||
|   if (!conn->easy) { | ||||
|     fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n"); | ||||
|     exit(2); | ||||
|   } | ||||
|   conn->global = g; | ||||
|   conn->url = strdup(url); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 0); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); | ||||
|   curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); | ||||
|   fprintf(MSG_OUT, | ||||
|           "Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); | ||||
|   rc =curl_multi_add_handle(g->multi, conn->easy); | ||||
|   mcode_or_die("new_conn: curl_multi_add_handle", rc); | ||||
|   do { | ||||
|     rc = curl_multi_socket_all(g->multi, &g->still_running); | ||||
|   } while (CURLM_CALL_MULTI_PERFORM == rc); | ||||
|   mcode_or_die("new_conn: curl_multi_socket_all", rc); | ||||
|   check_run_count(g); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* This gets called whenever data is received from the fifo */ | ||||
| void fifo_cb(int fd, short event, void *arg) { | ||||
|   char s[1024]; | ||||
|   long int rv=0; | ||||
|   int n=0; | ||||
|   GlobalInfo *g = (GlobalInfo *)arg; | ||||
|  | ||||
|   do { | ||||
|     s[0]='\0'; | ||||
|     rv=fscanf(g->input, "%1023s%n", s, &n); | ||||
|     s[n]='\0'; | ||||
|     if ( n && s[0] ) { | ||||
|       new_conn(s,arg);  /* if we read a URL, go get it! */ | ||||
|     } else break; | ||||
|   } while ( rv != EOF); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Create a named pipe and tell libevent to monitor it */ | ||||
| int init_fifo (GlobalInfo *g) { | ||||
|   struct stat st; | ||||
|   char *fifo = "hiper.fifo"; | ||||
|   int socket; | ||||
|  | ||||
|   fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo); | ||||
|   if (lstat (fifo, &st) == 0) { | ||||
|     if ((st.st_mode & S_IFMT) == S_IFREG) { | ||||
|       errno = EEXIST; | ||||
|       perror("lstat"); | ||||
|       exit (1); | ||||
|     } | ||||
|   } | ||||
|   unlink(fifo); | ||||
|   if (mkfifo (fifo, 0600) == -1) { | ||||
|     perror("mkfifo"); | ||||
|     exit (1); | ||||
|   } | ||||
|   socket = open(fifo, O_RDWR | O_NONBLOCK, 0); | ||||
|   if (socket == -1) { | ||||
|      perror("open"); | ||||
|      exit (1); | ||||
|   } | ||||
|   g->input = fdopen(socket, "r"); | ||||
|  | ||||
|   fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo); | ||||
|   event_set(&g->fifo_event, socket, EV_READ | EV_PERSIST, fifo_cb, g); | ||||
|   event_add(&g->fifo_event, NULL); | ||||
|   return (0); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|   GlobalInfo g; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   memset(&g, 0, sizeof(GlobalInfo)); | ||||
|   event_init(); | ||||
|   init_fifo(&g); | ||||
|   g.multi = curl_multi_init(); | ||||
|   evtimer_set(&g.timer_event, timer_cb, &g); | ||||
|   curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb); | ||||
|   curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g); | ||||
|   do { | ||||
|     rc = curl_multi_socket_all(g.multi, &g.still_running); | ||||
|   } while (CURLM_CALL_MULTI_PERFORM == rc); | ||||
|   update_timeout(&g); | ||||
|   event_dispatch(); | ||||
|   curl_multi_cleanup(g.multi); | ||||
|   return 0; | ||||
| } | ||||
| @@ -87,8 +87,10 @@ int main(int argc, char **argv) | ||||
|     /* now specify which file to upload */ | ||||
|     curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); | ||||
|  | ||||
|     /* and give the size of the upload */ | ||||
|     curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_info.st_size); | ||||
|     /* provide the size of the upload, we specicially typecast the value | ||||
|        to curl_off_t since we must be sure to use the correct data size */ | ||||
|     curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, | ||||
|                      (curl_off_t)file_info.st_size); | ||||
|  | ||||
|     /* Now run off and do what you've been told! */ | ||||
|     res = curl_easy_perform(curl); | ||||
|   | ||||
| @@ -15,13 +15,13 @@ endif | ||||
|  | ||||
| LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a | ||||
|  | ||||
| PROGRAMS  = fopen.exe ftpget.exe ftpgetresp.exe ftpupload.exe \ | ||||
|             getinmemory.exe http-post.exe httpput.exe multi-app.exe \ | ||||
|             multi-double.exe multi-post.exe multi-single.exe \ | ||||
|             persistant.exe post-callback.exe postit2.exe \ | ||||
|             sepheaders.exe simple.exe simplessl.exe https.exe \ | ||||
|             ftp3rdparty.exe getinfo.exe anyauthput.exe \ | ||||
|             cookie_interface.exe | ||||
| CSOURCES = fopen.c ftpget.c ftpgetresp.c ftpupload.c getinmemory.c \ | ||||
|            http-post.c httpput.c multi-app.c multi-double.c multi-post.c \ | ||||
|            multi-single.c persistant.c post-callback.c postit2.c \ | ||||
|            sepheaders.c simple.c simplessl.c https.c ftp3rdparty.c \ | ||||
|            getinfo.c anyauthput.c cookie_interface.c 10-at-a-time.c | ||||
|  | ||||
| PROGRAMS = $(CSOURCES:.c=.exe) | ||||
|  | ||||
| all: $(PROGRAMS) | ||||
|  | ||||
| @@ -32,3 +32,5 @@ all: $(PROGRAMS) | ||||
| clean: | ||||
| 	rm -f $(PROGRAMS) | ||||
|  | ||||
| # DO NOT DELETE THIS LINE | ||||
|  | ||||
|   | ||||
| @@ -80,6 +80,10 @@ int main(int argc, char **argv) | ||||
|     /* get file descriptors from the transfers */ | ||||
|     curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||
|  | ||||
|     /* In a real-world program you OF COURSE check the return code of the | ||||
|        function calls, *and* you make sure that maxfd is bigger than -1 so | ||||
|        that the call to select() below makes sense! */ | ||||
|  | ||||
|     rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||
|  | ||||
|     switch(rc) { | ||||
|   | ||||
| @@ -153,6 +153,10 @@ int main(int argc, char **argv) | ||||
|     /* get file descriptors from the transfers */ | ||||
|     curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||
|  | ||||
|     /* In a real-world program you OF COURSE check the return code of the | ||||
|        function calls, *and* you make sure that maxfd is bigger than -1 | ||||
|        so that the call to select() below makes sense! */ | ||||
|  | ||||
|     rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||
|  | ||||
|     switch(rc) { | ||||
|   | ||||
| @@ -71,6 +71,10 @@ int main(int argc, char **argv) | ||||
|     /* get file descriptors from the transfers */ | ||||
|     curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||
|  | ||||
|     /* In a real-world program you OF COURSE check the return code of the | ||||
|        function calls, *and* you make sure that maxfd is bigger than -1 so | ||||
|        that the call to select() below makes sense! */ | ||||
|  | ||||
|     rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||
|  | ||||
|     switch(rc) { | ||||
|   | ||||
| @@ -93,6 +93,10 @@ int main(int argc, char *argv[]) | ||||
|       /* get file descriptors from the transfers */ | ||||
|       curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||
|  | ||||
|       /* In a real-world program you OF COURSE check the return code of the | ||||
|          function calls, *and* you make sure that maxfd is bigger than -1 | ||||
|          so that the call to select() below makes sense! */ | ||||
|  | ||||
|       rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||
|  | ||||
|       switch(rc) { | ||||
|   | ||||
| @@ -65,6 +65,10 @@ int main(int argc, char **argv) | ||||
|     /* get file descriptors from the transfers */ | ||||
|     curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); | ||||
|  | ||||
|     /* In a real-world program you OF COURSE check the return code of the | ||||
|        function calls, *and* you make sure that maxfd is bigger than -1 so | ||||
|        that the call to select() below makes sense! */ | ||||
|  | ||||
|     rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); | ||||
|  | ||||
|     switch(rc) { | ||||
|   | ||||
| @@ -59,7 +59,9 @@ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <time.h> | ||||
| #ifndef __CYGWIN__ | ||||
| #include <windows.h> | ||||
| #endif | ||||
| #include <curl/curl.h> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3	 \ | ||||
|  curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3	 \ | ||||
|  libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3		 \ | ||||
|  curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3		 \ | ||||
|  curl_multi_timeout.3 | ||||
|  curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 | ||||
|  | ||||
| HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html		  \ | ||||
|  curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html	  \ | ||||
| @@ -35,7 +35,8 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html		  \ | ||||
|  libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html	  \ | ||||
|  curl_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \ | ||||
|  curl_easy_reset.html curl_easy_escape.html curl_easy_unescape.html	  \ | ||||
|  curl_multi_setopt.html curl_multi_socket.html curl_multi_timeout.html | ||||
|  curl_multi_setopt.html curl_multi_socket.html curl_multi_timeout.html	  \ | ||||
|  curl_formget.html curl_multi_assign.html | ||||
|  | ||||
| PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \ | ||||
|  curl_easy_perform.pdf curl_easy_setopt.pdf curl_easy_duphandle.pdf	  \ | ||||
| @@ -51,7 +52,8 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \ | ||||
|  libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf	  \ | ||||
|  curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf	  \ | ||||
|  curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf	  \ | ||||
|  curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf | ||||
|  curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf	  \ | ||||
|  curl_formget.pdf curl_multi_assign.pdf | ||||
|  | ||||
| CLEANFILES = $(HTMLPAGES) $(PDFPAGES) | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| .\" nroff -man [file] | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_easy_cleanup 3 "13 Nov 2002" "libcurl 7.7" "libcurl Manual" | ||||
| .TH curl_easy_cleanup 3 "12 Oct 2006" "libcurl 7.7" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_easy_cleanup - End a libcurl easy session | ||||
| .SH SYNOPSIS | ||||
| @@ -21,6 +21,9 @@ more files. | ||||
|  | ||||
| When you've called this, you can safely remove all the strings you've | ||||
| previously told libcurl to use, as it won't use them anymore now. | ||||
|  | ||||
| Any uses of the \fBhandle\fP after this function has been called are | ||||
| illegal. This kills the handle and all memory associated with it! | ||||
| .SH RETURN VALUE | ||||
| None | ||||
| .SH "SEE ALSO" | ||||
|   | ||||
| @@ -160,20 +160,37 @@ found in \fI<curl/curl.h>\fP. This function gets called by libcurl when | ||||
| something special I/O-related needs to be done that the library can't do by | ||||
| itself. For now, rewinding the read data stream is the only action it can | ||||
| request. The rewinding of the read data stream may be necessary when doing a | ||||
| HTTP PUT or POST with a multi-pass authentication method.  (Opion added in | ||||
| HTTP PUT or POST with a multi-pass authentication method.  (Option added in | ||||
| 7.12.3) | ||||
| .IP CURLOPT_IOCTLDATA | ||||
| Pass a pointer that will be untouched by libcurl and passed as the 3rd | ||||
| argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP.  (Option | ||||
| added in 7.12.3) | ||||
| .IP CURLOPT_SOCKOPTFUNCTION | ||||
| Function pointer that should match the \fIcurl_sockopt_callback\fP prototype | ||||
| found in \fI<curl/curl.h>\fP. This function gets called by libcurl after the | ||||
| socket() call but before the connect() 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 newly created | ||||
| socket descriptor so additional setsockopt() calls can be done at the user's | ||||
| discretion.  A non-zero return code from the callback function will signal an | ||||
| unrecoverable error to the library and it will close the socket and return | ||||
| \fICURLE_COULDNT_CONNECT\fP.  (Option added in 7.15.6.) | ||||
| .IP CURLOPT_SOCKOPTDATA | ||||
| Pass a pointer that will be untouched by libcurl and passed as the first | ||||
| argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP. | ||||
| (Option added in 7.15.6.) | ||||
| .IP CURLOPT_PROGRESSFUNCTION | ||||
| Function pointer that should match the \fIcurl_progress_callback\fP prototype | ||||
| found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of | ||||
| its internal equivalent with a frequent interval during data transfer (roughly | ||||
| once per second).  Unknown/unused argument values pass to the callback will be | ||||
| set to zero (like if you only download data, the upload size will remain | ||||
| 0). Returning a non-zero value from this callback will cause libcurl to abort | ||||
| the transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP. | ||||
| its internal equivalent with a frequent interval during operation (roughly | ||||
| once per second) no matter if data is being transfered or not.  Unknown/unused | ||||
| argument values passed to the callback will be set to zero (like if you only | ||||
| download data, the upload size will remain 0). Returning a non-zero value from | ||||
| this callback will cause libcurl to abort the transfer and return | ||||
| \fICURLE_ABORTED_BY_CALLBACK\fP. | ||||
|  | ||||
| If you transfer data with the multi interface, this function will not be | ||||
| called during periods of idleness unless you call the appropriate libcurl | ||||
| @@ -327,6 +344,14 @@ when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data. | ||||
| A non-zero parameter tells the library to fail silently if the HTTP code | ||||
| returned is equal to or larger than 400. The default action would be to return | ||||
| the page normally, ignoring that code. | ||||
|  | ||||
| This method is not fail-safe and there are occasions where non-succesful | ||||
| response codes will slip through, especially when authentication is involved | ||||
| (response codes 401 and 407). | ||||
|  | ||||
| You might get some amounts of headers transferred before this situation is | ||||
| detected, like for when a "100-continue" is received as a response to a | ||||
| 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 | ||||
| @@ -364,9 +389,10 @@ libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP, | ||||
| \fBall_proxy\fP etc, if any of those is set. The \fICURLOPT_PROXY\fP option | ||||
| does however override any possibly set environment variables. | ||||
|  | ||||
| Starting with 7.14.1, the proxy host string can be specified the exact same | ||||
| way as the proxy environment variables, include protocol prefix (http://) and | ||||
| embedded user + password. | ||||
| Starting with 7.14.1, the proxy host string given in environment variables can | ||||
| be specified the exact same way as the proxy can be set with | ||||
| \fICURLOPT_PROXY\fP, include protocol prefix (http://) and embedded user + | ||||
| password. | ||||
| .IP CURLOPT_PROXYPORT | ||||
| Pass a long with this option to set the proxy port to connect to unless it is | ||||
| specified in the proxy string \fICURLOPT_PROXY\fP. | ||||
| @@ -820,7 +846,8 @@ Pass a pointer to a linked list of FTP commands to pass to the server after | ||||
| the transfer type is set. The linked list should be a fully valid list of | ||||
| struct curl_slist structs properly filled in as described for | ||||
| \fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this | ||||
| option. | ||||
| option. Before version 7.15.6, if you also set \fICURLOPT_NOBODY\fP non-zero, | ||||
| this option didn't work. | ||||
| .IP CURLOPT_FTPLISTONLY | ||||
| A non-zero parameter tells the library to just list the names of an ftp | ||||
| directory, instead of doing a full directory listing that would include file | ||||
| @@ -859,6 +886,12 @@ waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It is | ||||
| recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set | ||||
| \fICURLOPT_FTP_RESPONSE_TIMEOUT\fP to a value smaller than | ||||
| \fICURLOPT_TIMEOUT\fP.  (Added in 7.10.8) | ||||
| .IP CURLOPT_FTP_ALTERNATIVE_TO_USER | ||||
| Pass a char * as parameter, pointing to a string which will be used to | ||||
| authenticate if the usual FTP "USER user" and "PASS password" negotiation | ||||
| fails. This is currently only known to be required when connecting to | ||||
| Tumbleweed's Secure Transport FTPS server using client certificates for | ||||
| authentication. (Added in 7.15.5) | ||||
| .IP CURLOPT_FTP_SKIP_PASV_IP | ||||
| Pass a long. If set to a non-zero value, it instructs libcurl to not use the | ||||
| IP address the server suggests in its 227-response to libcurl's PASV command | ||||
| @@ -892,18 +925,6 @@ Try "AUTH SSL" first, and only if that fails try "AUTH TLS" | ||||
| .IP CURLFTPAUTH_TLS | ||||
| Try "AUTH TLS" first, and only if that fails try "AUTH SSL" | ||||
| .RE | ||||
| .IP CURLOPT_SOURCE_URL | ||||
| When set, it enables a FTP third party transfer, using the set URL as source, | ||||
| while \fICURLOPT_URL\fP is the target. | ||||
| .IP CURLOPT_SOURCE_USERPWD | ||||
| Set "username:password" to use for the source connection when doing FTP third | ||||
| party transfers. | ||||
| .IP CURLOPT_SOURCE_QUOTE | ||||
| Exactly like \fICURLOPT_QUOTE\fP, but for the source host. | ||||
| .IP CURLOPT_SOURCE_PREQUOTE | ||||
| Exactly like \fICURLOPT_PREQUOTE\fP, but for the source host. | ||||
| .IP CURLOPT_SOURCE_POSTQUOTE | ||||
| Exactly like \fICURLOPT_POSTQUOTE\fP, but for the source host. | ||||
| .IP CURLOPT_FTP_ACCOUNT | ||||
| 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, | ||||
| @@ -948,7 +969,9 @@ techniques). Pass a NULL to this option to disable the use of ranges. | ||||
| .IP CURLOPT_RESUME_FROM | ||||
| Pass a long as parameter. It contains the offset in number of bytes that you | ||||
| want the transfer to start from. Set this option to 0 to make the transfer | ||||
| start from the beginning (effectively disabling resume). | ||||
| start from the beginning (effectively disabling resume). For FTP, set this | ||||
| option to -1 to make the transfer start from the end of the target file | ||||
| (useful to continue an interrupted upload). | ||||
| .IP CURLOPT_RESUME_FROM_LARGE | ||||
| Pass a curl_off_t as parameter. It contains the offset in number of bytes that | ||||
| you want the transfer to start from. (Added in 7.11.0) | ||||
| @@ -991,9 +1014,9 @@ libcurl what the expected size of the infile is.  This value should be passed | ||||
| as a curl_off_t. (Added in 7.11.0) | ||||
| .IP CURLOPT_UPLOAD | ||||
| A non-zero parameter tells the library to prepare for an upload. The | ||||
| \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZEE\fP or | ||||
| \fICURLOPT_INFILESIZE_LARGE\fP are also interesting for uploads. If the | ||||
| protocol is HTTP, uploading means using the PUT request unless you tell | ||||
| \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP or | ||||
| \fICURLOPT_INFILESIZE_LARGE\fP options are also interesting for uploads. If | ||||
| the protocol is HTTP, uploading means using the PUT request unless you tell | ||||
| libcurl otherwise. | ||||
|  | ||||
| Using PUT with HTTP 1.1 implies the use of a "Expect: 100-continue" header. | ||||
| @@ -1051,6 +1074,16 @@ for the library to consider it too slow and abort. | ||||
| Pass a long as parameter. It contains the time in seconds that the transfer | ||||
| should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider | ||||
| it too slow and abort. | ||||
| .IP CURLOPT_MAX_SEND_SPEED_LARGE | ||||
| Pass a curl_off_t as parameter.  If an upload exceeds this speed on cumulative | ||||
| average during the transfer, the transfer will pause to keep the average rate | ||||
| less than or equal to the parameter value.  Defaults to unlimited | ||||
| speed. (Added in 7.15.5) | ||||
| .IP CURLOPT_MAX_RECV_SPEED_LARGE | ||||
| Pass a curl_off_t as parameter.  If an upload exceeds this speed on cumulative | ||||
| average during the transfer, the transfer will pause to keep the average rate | ||||
| less than or equal to the parameter value. Defaults to unlimited speed. (Added | ||||
| in 7.15.5) | ||||
| .IP CURLOPT_MAXCONNECTS | ||||
| Pass a long. The set number will be the persistent connection cache size. The | ||||
| set amount will be the maximum amount of simultaneously open connections that | ||||
| @@ -1111,7 +1144,7 @@ Resolve to ipv4 addresses. | ||||
| .IP CURL_IPRESOLVE_V6 | ||||
| Resolve to ipv6 addresses. | ||||
| .RE | ||||
| .SH CURLOPT_CONNECT_ONLY | ||||
| .IP CURLOPT_CONNECT_ONLY | ||||
| Pass a long. A non-zero parameter tells the library to perform any required | ||||
| proxy authentication and connection setup, but no data transfer. | ||||
|  | ||||
| @@ -1267,6 +1300,12 @@ compile OpenSSL. | ||||
|  | ||||
| You'll find more details about cipher lists on this URL: | ||||
| \fIhttp://www.openssl.org/docs/apps/ciphers.html\fP | ||||
| .IP CURLOPT_SSL_SESSIONID_CACHE | ||||
| Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set | ||||
| this to 1 to enable it. By default all transfers are done using the | ||||
| cache. Note that while nothing ever should get hurt by attempting to reuse SSL | ||||
| session-IDs, there seem to be broken SSL implementations in the wild that may | ||||
| require you to disable this in order for you to succeed. (Added in 7.16.0) | ||||
| .IP CURLOPT_KRB4LEVEL | ||||
| Pass a char * as parameter. Set the krb4 security level, this also enables | ||||
| krb4 awareness.  This is a string, 'clear', 'safe', 'confidential' or | ||||
|   | ||||
| @@ -23,88 +23,96 @@ After the \fIlastitem\fP pointer follow the real arguments. | ||||
|  | ||||
| The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to | ||||
| NULL in the first call to this function. All list-data will be allocated by | ||||
| the function itself. You must call \fIcurl_formfree\fP after the form post has | ||||
| been done to free the resources again. | ||||
| the function itself. You must call \fIcurl_formfree(3)\fP after the form post | ||||
| has been done to free the resources. | ||||
|  | ||||
| Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. | ||||
| You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. | ||||
|  | ||||
| First, there are some basics you need to understand about multipart/formdata | ||||
| posts. Each part consists of at least a NAME and a CONTENTS part. If the part | ||||
| is made for file upload, there are also a stored CONTENT-TYPE and a | ||||
| FILENAME. Below here, we'll discuss on what options you use to set these | ||||
| properties in the parts you want to add to your post. | ||||
| is made for file upload, there are also a stored CONTENT-TYPE and a FILENAME. | ||||
| Below, we'll discuss what options you use to set these properties in the | ||||
| parts you want to add to your post. | ||||
|  | ||||
| The options listed first are for making normal parts. The options from | ||||
| \fICURLFORM_FILE\fP through \fICURLFORM_BUFFERLENGTH\fP are for file upload | ||||
| parts. | ||||
|  | ||||
| .SH OPTIONS | ||||
|  | ||||
| .IP CURLFORM_COPYNAME | ||||
| followed by string is used to set the name of this part. libcurl copies the | ||||
| given data, so your application doesn't need to keep it around after this | ||||
| function call. If the name isn't zero terminated properly, or if you'd like it | ||||
| to contain zero bytes, you need to set the length of the name with | ||||
| \fBCURLFORM_NAMELENGTH\fP. | ||||
| followed by a string which provides the \fIname\fP of this part. libcurl | ||||
| copies the string so your application doesn't need to keep it around after | ||||
| this function call. If the name isn't null terminated, or if you'd | ||||
| like it to contain zero bytes, you must set its length with | ||||
| \fBCURLFORM_NAMELENGTH\fP. The copied data will be freed by | ||||
| \fIcurl_formfree(3)\fP. | ||||
|  | ||||
| .IP CURLFORM_PTRNAME | ||||
| followed by a string is used for the name of this part. libcurl will use the | ||||
| pointer and refer to the data in your application, you must make sure it | ||||
| remains until curl no longer needs it. If the name isn't zero terminated | ||||
| properly, or if you'd like it to contain zero bytes, you need to set the | ||||
| length of the name with \fBCURLFORM_NAMELENGTH\fP. | ||||
| followed by a string which provides the \fIname\fP of this part. libcurl | ||||
| will use the pointer and refer to the data in your application, so you | ||||
| must make sure it remains until curl no longer needs it. If the name | ||||
| isn't null terminated, or if you'd like it to contain zero | ||||
| bytes, you must set its length with \fBCURLFORM_NAMELENGTH\fP. | ||||
|  | ||||
| .IP CURLFORM_COPYCONTENTS | ||||
| followed by a string is used for the contents of this part, the actual data to | ||||
| send away. libcurl copies the given data, so your application doesn't need to | ||||
| keep it around after this function call. If the data isn't zero terminated | ||||
| properly, or if you'd like it to contain zero bytes, you need to set the | ||||
| length of the name with \fBCURLFORM_CONTENTSLENGTH\fP. | ||||
| followed by a pointer to the contents of this part, the actual data | ||||
| to send away. libcurl copies the provided data, so your application doesn't | ||||
| need to keep it around after this function call. If the data isn't null | ||||
| terminated, or if you'd like it to contain zero bytes, you must | ||||
| set the length of the name with \fBCURLFORM_CONTENTSLENGTH\fP. The copied | ||||
| data will be freed by \fIcurl_formfree(3)\fP. | ||||
|  | ||||
| .IP CURLFORM_PTRCONTENTS | ||||
| followed by a string is used for the contents of this part, the actual data to | ||||
| send away. libcurl will use the pointer and refer to the data in your | ||||
| application, you must make sure it remains until curl no longer needs it. If | ||||
| the data isn't zero terminated properly, or if you'd like it to contain zero | ||||
| bytes, you need to set the length of the name with | ||||
| \fBCURLFORM_CONTENTSLENGTH\fP. | ||||
| followed by a pointer to the contents of this part, the actual data | ||||
| to send away. libcurl will use the pointer and refer to the data in your | ||||
| application, so you must make sure it remains until curl no longer needs it. | ||||
| If the data isn't null terminated, or if you'd like it to contain zero bytes, | ||||
| you must set its length  with \fBCURLFORM_CONTENTSLENGTH\fP. | ||||
|  | ||||
| .IP CURLFORM_CONTENTSLENGTH | ||||
| followed by a long setting the length of the contents. | ||||
| followed by a long giving the length of the contents. | ||||
|  | ||||
| .IP CURLFORM_FILECONTENT | ||||
| followed by a file name, makes that file read and the contents will be used in | ||||
| as data in this part. | ||||
| followed by a filename, causes that file to be read and its contents used | ||||
| as data in this part. This part does \fInot\fP automatically become a file | ||||
| upload part simply because its data was read from a file. | ||||
|  | ||||
| .IP CURLFORM_FILE | ||||
| followed by a file name, makes this part a file upload part. It sets the file | ||||
| name field to the actual file name used here, it gets the contents of the file | ||||
| and passes as data and sets the content-type if the given file match one of | ||||
| the new internally known file extension.  For \fBCURLFORM_FILE\fP the user may | ||||
| send one or more files in one part by providing multiple \fBCURLFORM_FILE\fP | ||||
| arguments each followed by the filename (and each CURLFORM_FILE is allowed to | ||||
| have a CURLFORM_CONTENTTYPE). | ||||
| followed by a filename, makes this part a file upload part. It sets the | ||||
| \fIfilename\fP field to the basename of the provided filename, it reads the | ||||
| contents of the file and passes them as data and sets the content-type if the | ||||
| given file match one of the internally known file extensions.  For | ||||
| \fBCURLFORM_FILE\fP the user may send one or more files in one part by | ||||
| providing multiple \fBCURLFORM_FILE\fP arguments each followed by the | ||||
| filename (and each CURLFORM_FILE is allowed to have a CURLFORM_CONTENTTYPE). | ||||
|  | ||||
| .IP CURLFORM_CONTENTTYPE | ||||
| followed by a pointer to a string with a content-type will make curl use this | ||||
| given content-type for this file upload part, possibly instead of an | ||||
| is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a | ||||
| string which provides the content-type for this part, possibly instead of an | ||||
| internally chosen one. | ||||
|  | ||||
| .IP CURLFORM_FILENAME | ||||
| followed by a pointer to a string to a name, will make libcurl use the given | ||||
| name in the file upload part, instead of the actual file name given to | ||||
| \fICURLFORM_FILE\fP. | ||||
| is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a | ||||
| string, it tells libcurl to use the given string as the \fIfilename\fP in the | ||||
| file upload part instead of the actual file name. | ||||
|  | ||||
| .IP CURLFORM_BUFFER | ||||
| followed by a string, tells libcurl that a buffer is to be used to upload data | ||||
| instead of using a file. The given string is used as the value of the file | ||||
| name field in the content header. | ||||
| is used for custom file upload parts without use of \fICURLFORM_FILE\fP.  It | ||||
| tells libcurl that the file contents are already present in a buffer.  The | ||||
| parameter is a string which provides the \fIfilename\fP field in the content | ||||
| header. | ||||
|  | ||||
| .IP CURLFORM_BUFFERPTR | ||||
| followed by a pointer to a data area, tells libcurl the address of the buffer | ||||
| containing data to upload (as indicated with \fICURLFORM_BUFFER\fP). The | ||||
| buffer containing this data must not be freed until after | ||||
| is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a pointer | ||||
| to the buffer to be uploaded. This buffer must not be freed until after | ||||
| \fIcurl_easy_cleanup(3)\fP is called. You must also use | ||||
| \fICURLFORM_BUFFERLENGTH\fP to set the length of the given buffer area. | ||||
| \fICURLFORM_BUFFERLENGTH\fP to set the number of bytes in the buffer. | ||||
|  | ||||
| .IP CURLFORM_BUFFERLENGTH | ||||
| followed by a long with the size of the \fICURLFORM_BUFFERPTR\fP data area, | ||||
| tells libcurl the length of the buffer to upload. | ||||
| is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a | ||||
| long which gives the length of the buffer. | ||||
|  | ||||
| .IP CURLFORM_ARRAY | ||||
| Another possibility to send options to curl_formadd() is the | ||||
|   | ||||
							
								
								
									
										49
									
								
								docs/libcurl/curl_formget.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/libcurl/curl_formget.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| .\" You can view this file with: | ||||
| .\" nroff -man [file] | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_formget 3 "20 June 2006" "libcurl 7.15.5" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_formget - serialize a previously build multipart/formdata HTTP POST chain | ||||
| .SH SYNOPSIS | ||||
| .B #include <curl/curl.h> | ||||
| .sp | ||||
| .BI "void curl_formget(struct curl_httppost *" form, " void *" arg, | ||||
| .BI " curl_formget_callback " append ");" | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| curl_formget() is used to serialize data previously built/appended with | ||||
| \fIcurl_formadd(3)\fP. Accepts a void pointer as second argument which will be | ||||
| passed to the curl_formget_callback function. | ||||
|  | ||||
| .BI "typedef size_t (*curl_formget_callback)(void *" arg, " const char *" buf, | ||||
| .BI " size_t " len ");" | ||||
| .nf | ||||
|  | ||||
| The curl_formget_callback will be executed for each part of the HTTP POST | ||||
| chain. The void *arg pointer will be the one passed as second argument to | ||||
| curl_formget(). The character buffer passed to it must not be freed. The  | ||||
| callback should return the buffer length passed to it on success. | ||||
| .SH RETURN VALUE | ||||
| 0 means everything was ok, non-zero means an error occurred | ||||
| .SH EXAMPLE | ||||
| .nf | ||||
|  | ||||
|  size_t print_httppost_callback(void *arg, const char *buf, size_t len) | ||||
|  { | ||||
|    fwrite(buf, len, 1, stdout); | ||||
|    (*(size_t *) arg) += len; | ||||
|    return len; | ||||
|  } | ||||
|  size_t print_httppost(struct curl_httppost *post) | ||||
|  { | ||||
|    size_t total_size = 0; | ||||
|    if(curl_formget(post, &total_size, print_httppost_callback)) { | ||||
|      return (size_t) -1; | ||||
|    } | ||||
|    return total_size; | ||||
|  } | ||||
| .SH AVAILABILITY | ||||
| This function was added in libcurl 7.15.5 | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_formadd "(3) " | ||||
| @@ -11,30 +11,30 @@ curl_global_init - Global libcurl initialisation | ||||
| .BI "CURLcode curl_global_init(long " flags ");" | ||||
| .ad | ||||
| .SH DESCRIPTION | ||||
| This function sets up the program environment that libcurl needs.  Think | ||||
| of it as an extension of the library loader. | ||||
| This function sets up the program environment that libcurl needs.  Think of it | ||||
| as an extension of the library loader. | ||||
|  | ||||
| This function must be called at least once within a program (a program is | ||||
| all the code that shares a memory space) before the program calls any other | ||||
| function in libcurl.  The environment it sets up is constant for the life | ||||
| of the program and is the same for every program, so multiple calls have | ||||
| the same effect as one call. | ||||
| This function must be called at least once within a program (a program is all | ||||
| the code that shares a memory space) before the program calls any other | ||||
| function in libcurl.  The environment it sets up is constant for the life of | ||||
| the program and is the same for every program, so multiple calls have the same | ||||
| effect as one call. | ||||
|  | ||||
| The flags option is a bit pattern that tells libcurl exactly what features to | ||||
| init, as described below. Set the desired bits by ORing the values together. | ||||
| In normal operation, you must specify CURL_GLOBAL_ALL.  Don't use any other | ||||
| value unless you are familiar with and mean to control internal operations | ||||
| of libcurl. | ||||
| value unless you are familiar with and mean to control internal operations of | ||||
| libcurl. | ||||
|  | ||||
| \fBThis function is not thread safe.\fP  You must not call it when any | ||||
| other thread in the program (i.e. a thread sharing the same memory) is | ||||
| running.  This doesn't just mean no other thread that is using | ||||
| libcurl.  Because \fIcurl_global_init()\fP calls functions of other | ||||
| libraries that are similarly thread unsafe, it could conflict with any | ||||
| other thread that uses these other libraries. | ||||
| \fBThis function is not thread safe.\fP You must not call it when any other | ||||
| thread in the program (i.e. a thread sharing the same memory) is running. | ||||
| This doesn't just mean no other thread that is using libcurl.  Because | ||||
| \fIcurl_global_init()\fP calls functions of other libraries that are similarly | ||||
| thread unsafe, it could conflict with any other thread that uses these other | ||||
| libraries. | ||||
|  | ||||
| See the description in \fBlibcurl\fP(3) of global environment | ||||
| requirements for details of how to use this function. | ||||
| See the description in \fBlibcurl\fP(3) of global environment requirements for | ||||
| details of how to use this function. | ||||
|  | ||||
| .SH FLAGS | ||||
| .TP 5 | ||||
|   | ||||
| @@ -15,6 +15,11 @@ this \fImulti_handle\fP control the specified \fIeasy_handle\fP. | ||||
| When an easy handle has been added to a multi stack, you can not and you must | ||||
| not use \fIcurl_easy_perform(3)\fP on that handle! | ||||
|  | ||||
| If the easy handle is not set to use a shared (CURLOPT_SHARE) or global DNS | ||||
| cache (CURLOPT_DNS_USE_GLOBAL_CACHE), it will be made to use the DNS cache | ||||
| that is shared between all easy handles within the multi handle when | ||||
| \fIcurl_multi_add_handle(3)\fP is called. | ||||
|  | ||||
| The easy handle will remain added until you remove it again with | ||||
| \fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the | ||||
| multi stack before you terminate first the easy handle and then the multi | ||||
|   | ||||
							
								
								
									
										44
									
								
								docs/libcurl/curl_multi_assign.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								docs/libcurl/curl_multi_assign.3
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_multi_assign \- set data to associated with an internal socket | ||||
| .SH SYNOPSIS | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd, | ||||
|                             void *sockptr); | ||||
| .SH DESCRIPTION | ||||
| This function assigns an association in the multi handle between the given | ||||
| socket and a private pointer of the application. This is (only) useful for | ||||
| \fIcurl_multi_socket(3)\fP uses. | ||||
|  | ||||
| When set, the \fIsockptr\fP pointer will be passed to all future socket | ||||
| callbacks for the specific \fIsockfd\fP socket. | ||||
|  | ||||
| If the given \fIsockfd\fP isn't already in use by libcurl, this function will | ||||
| return an error. | ||||
|  | ||||
| libcurl only keeps one single pointer associated with a socket, so calling | ||||
| this function several times for the same socket will make the last set pointer | ||||
| get used. | ||||
|  | ||||
| The idea here being that this association (socket to private pointer) is | ||||
| something that just about every application that uses this API will need and | ||||
| then libcurl can just as well do it since it already has an internal hash | ||||
| table lookup for this. | ||||
| .SH "RETURN VALUE" | ||||
| The standard CURLMcode for multi interface error codes. | ||||
| .SH "TYPICAL USAGE" | ||||
| In a typical application you allocate a struct or at least use some kind of | ||||
| semi-dynamic data for each socket that we must wait for action on when using | ||||
| the \fIcurl_multi_socket(3)\fP approach. | ||||
|  | ||||
| When our socket-callback get called by libcurl and we get to know about yet | ||||
| another socket to wait for, we can use \fIcurl_multi_assign(3)\fP to point out | ||||
| the particular data so that when we get updates about this same socket again, | ||||
| we don't have to find the struct associated with this socket by ourselves. | ||||
| .SH AVAILABILITY | ||||
| This function was added in libcurl 7.15.5, although not deemed stable yet. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_multi_setopt "(3), " curl_multi_socket "(3) " | ||||
| @@ -20,6 +20,11 @@ NULL is returned as a signal that there is no more to get at this point. The | ||||
| integer pointed to with \fImsgs_in_queue\fP will contain the number of | ||||
| remaining messages after this function was called. | ||||
|  | ||||
| When you fetch a message using this function, it is removed from the internal | ||||
| queue so calling this function again will not return the same message | ||||
| again. It will instead return new messages at each new invoke until the queue | ||||
| is emptied. | ||||
|  | ||||
| The data the returned pointer points to will not survive calling | ||||
| \fIcurl_multi_cleanup(3)\fP or \fIcurl_multi_remove_handle(3)\fP. | ||||
|  | ||||
| @@ -37,6 +42,12 @@ present in that struct and can thus be used in subsequent regular | ||||
|      CURLcode result;   /* return code for transfer */ | ||||
|    } data; | ||||
|  }; | ||||
|  | ||||
| When \fBmsg\fP is \fICURLMSG_DONE\fP, the message identifies a transfer that | ||||
| is done, and then \fBresult\fP contains the return code for the easy handle | ||||
| that just completed. | ||||
|  | ||||
| At this point, there is no other \fBmsg\fP types defined. | ||||
| .SH "RETURN VALUE" | ||||
| A pointer to a filled-in struct, or NULL if it failed or ran out of | ||||
| structs. It also writes the number of messages left in the queue (after this | ||||
|   | ||||
| @@ -30,11 +30,15 @@ If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you | ||||
| should call \fIcurl_multi_perform\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". | ||||
| to send off before it is "satisfied". Do note that \fIcurl_multi_perform(3)\fP | ||||
| will return \fICURLM_CALL_MULTI_PERFORM\fP only when it wants to be called | ||||
| again \fBimmediately\fP. When things are fine and there are nothing immediate | ||||
| it wants done, it'll return \fICURLM_OK\fP and you need to wait for \&"action" | ||||
| and then call this function again. | ||||
|  | ||||
| NOTE that this only returns errors etc regarding the whole multi stack. There | ||||
| might still have occurred problems on individual transfers even when this | ||||
| function returns OK. | ||||
| function returns \fICURLM_OK\fP. | ||||
| .SH "TYPICAL USAGE" | ||||
| Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's | ||||
| file descriptors, then it'll wait for action on them using \fBselect(3)\fP and | ||||
| @@ -42,4 +46,5 @@ as soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets | ||||
| called. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_multi_cleanup "(3), " curl_multi_init "(3), " | ||||
| .BR curl_multi_fdset "(3), " curl_multi_info_read "(3)" | ||||
| .BR curl_multi_fdset "(3), " curl_multi_info_read "(3), " | ||||
| .BR libcurl-errors "(3)" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_multi_setopt 3 "8 Jan 2006" "libcurl 7.16.0" "libcurl Manual" | ||||
| .TH curl_multi_setopt 3 "10 Oct 2006" "libcurl 7.16.0" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_multi_setopt \- set options for a curl multi handle | ||||
| .SH SYNOPSIS | ||||
| @@ -9,7 +9,7 @@ curl_multi_setopt \- set options for a curl multi handle | ||||
| CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param); | ||||
| .SH DESCRIPTION | ||||
| curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By | ||||
| using the appropriate options to \fIcurl_multi_setopt\fP, you can change | ||||
| using the appropriate options to \fIcurl_multi_setopt(3)\fP, you can change | ||||
| libcurl's behaviour when using that multi handle.  All options are set with | ||||
| the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be | ||||
| a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a | ||||
| @@ -19,24 +19,49 @@ You can only set one option in each function call. | ||||
|  | ||||
| .SH OPTIONS | ||||
| .IP CURLMOPT_SOCKETFUNCTION | ||||
| Pass a pointer to a function matching the curl_socket_callback prototype. The | ||||
| \fIcurl_multi_socket(3)\fP functions inform the application about updates in | ||||
| the socket (file descriptor) status by doing none, one or multiple calls to | ||||
| the curl_socket_callback given in the \fBparam\fP argument. They update the | ||||
| status with changes since the previous time a \fIcurl_multi_socket(3)\fP | ||||
| function was called. If the given callback pointer is NULL, no callback will | ||||
| be called. Set the callback's fourth argument with \fICURLMOPT_SOCKETDATA\fP. | ||||
| See \fIcurl_multi_socket(3)\fP for more callback details. | ||||
| Pass a pointer to a function matching the \fBcurl_socket_callback\fP | ||||
| prototype. The \fIcurl_multi_socket(3)\fP functions inform the application | ||||
| about updates in the socket (file descriptor) status by doing none, one or | ||||
| multiple calls to the curl_socket_callback given in the \fBparam\fP | ||||
| argument. They update the status with changes since the previous time a | ||||
| \fIcurl_multi_socket(3)\fP function was called. If the given callback pointer | ||||
| is NULL, no callback will be called. Set the callback's \fBuserp\fP argument | ||||
| with \fICURLMOPT_SOCKETDATA\fP.  See \fIcurl_multi_socket(3)\fP for more | ||||
| callback details. | ||||
| .IP CURLMOPT_SOCKETDATA | ||||
| Pass a pointer to whatever you want passed to the curl_socket_callback's forth | ||||
| argument, the userp pointer. This is not used by libcurl but only passed-thru | ||||
| as-is. Set the callback pointer with \fICURLMOPT_SOCKETFUNCTION\fP. | ||||
| Pass a pointer to whatever you want passed to the \fBcurl_socket_callback\fP's | ||||
| forth argument, the userp pointer. This is not used by libcurl but only | ||||
| passed-thru as-is. Set the callback pointer with | ||||
| \fICURLMOPT_SOCKETFUNCTION\fP. | ||||
| .IP CURLMOPT_PIPELINING | ||||
| Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi | ||||
| handle will make it attempt to perform HTTP Pipelining as far as possible for | ||||
| transfers using this handle. This means that if you add a second request that | ||||
| can use an already existing connection, the second request will be \&"piped" | ||||
| on the same connection rather than being executed in parallell. (Added in | ||||
| 7.16.0) | ||||
| .IP CURLMOPT_TIMERFUNCTION | ||||
| Pass a pointer to a function matching the \fBcurl_multi_timer_callback\fP | ||||
| prototype.  This function will then be called when the timeout value | ||||
| changes. The timeout value is at what latest time the application should call | ||||
| one of the \&"performing" functions of the multi interface | ||||
| (\fIcurl_multi_socket(3)\fP, \fIcurl_multi_socket_all(3)\fP and | ||||
| \fIcurl_multi_perform(3)\fP) - to allow libcurl to keep timeouts and retries | ||||
| etc to work. Libcurl attempts to limit calling this only when the fixed future | ||||
| timeout time actually change. See also \fICURLMOPT_TIMERDATA\fP. This callback | ||||
| can be used instead of, or in addition to, \fIcurl_multi_timeout(3)\fP. (Added | ||||
| in 7.16.0) | ||||
| .IP CURLMOPT_TIMERDATA | ||||
| Pass a pointer to whatever you want passed to the | ||||
| \fBcurl_multi_timer_callback\fP's third argument, the userp pointer.  This is | ||||
| not used by libcurl but only passed-thru as-is. Set the callback pointer with | ||||
| \fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0) | ||||
| .SH RETURNS | ||||
| The standard CURLMcode for multi interface error codes. Note that it returns a | ||||
| CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl | ||||
| doesn't know of. | ||||
| .SH AVAILABILITY | ||||
| This function was added in libcurl 7.16.0 | ||||
| This function was added in libcurl 7.15.4. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_multi_cleanup "(3), " curl_multi_init "(3), " | ||||
| .BR curl_multi_socket "(3), " curl_multi_info_read "(3)" | ||||
|   | ||||
| @@ -1,50 +1,71 @@ | ||||
| .\" $Id$ | ||||
| .\" | ||||
| .TH curl_multi_socket 3 "21 Dec 2005" "libcurl 7.16.0" "libcurl Manual" | ||||
| .TH curl_multi_socket 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual" | ||||
| .SH NAME | ||||
| curl_multi_socket \- reads/writes available data | ||||
| .SH SYNOPSIS | ||||
| #include <curl/curl.h> | ||||
|  | ||||
| CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd); | ||||
| CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd, | ||||
|                             int *running_handles); | ||||
|  | ||||
| CURLMcode curl_multi_socket_all(CURLM *multi_handle); | ||||
| CURLMcode curl_multi_socket_all(CURLM *multi_handle, | ||||
|                                 int *running_handles); | ||||
| .SH DESCRIPTION | ||||
| Alternative versions of \fIcurl_multi_perform()\fP that allows the application | ||||
| to pass in one of the file descriptors/sockets that have been detected to have | ||||
| \&"action" on them and let libcurl perform. This allows libcurl to not have to | ||||
| scan through all possible file descriptors to check for action. When the | ||||
| application has detected action on a socket handled by libcurl, it should call | ||||
| \fIcurl_multi_perform()\fP with the \fBsockfd\fP argument set to the socket | ||||
| with the action. | ||||
| Alternative versions of \fIcurl_multi_perform(3)\fP that allows the | ||||
| application to pass in one of the file descriptors/sockets that have been | ||||
| detected to have \&"action" on them and let libcurl perform. This allows | ||||
| libcurl to not have to scan through all possible file descriptors to check for | ||||
| action. When the application has detected action on a socket handled by | ||||
| libcurl, it should call \fIcurl_multi_socket(3)\fP with the \fBsockfd\fP | ||||
| argument set to the socket with the action. | ||||
|  | ||||
| These functions inform the application about updates in the socket (file | ||||
| descriptor) status by doing none, one or multiple calls to the | ||||
| curl_socket_callback given with the CURLMOPT_SOCKETFUNCTION option to | ||||
| At return, the int \fBrunning_handles\fP points to will contain the number of | ||||
| still running easy handles within the multi handle. When this number reaches | ||||
| zero, all transfers are complete/done. Note that when you call | ||||
| \fIcurl_multi_socket(3)\fP on a specific socket and the counter decreases by | ||||
| one, it DOES NOT necessarily mean that this exact socket/transfer is the one | ||||
| that completed. Use \fIcurl_multi_info_read(3)\fP to figure out which easy | ||||
| handle that completed. | ||||
|  | ||||
| The curl_multi_socket functions inform the application about updates in the | ||||
| socket (file descriptor) status by doing none, one or multiple calls to the | ||||
| socket callback function set with the CURLMOPT_SOCKETFUNCTION option to | ||||
| \fIcurl_multi_setopt(3)\fP. They update the status with changes since the | ||||
| previous time this function was called. | ||||
|  | ||||
| If you want to force libcurl to (re-)check all its internal sockets and | ||||
| transfers instead of just a single one, you call | ||||
| \fBcurl_multi_socket_all(3)\fP instead. | ||||
| To force libcurl to (re-)check all its internal sockets and transfers instead | ||||
| of just a single one, you call \fBcurl_multi_socket_all(3)\fP. This is | ||||
| typically done as the first function call before the application has any | ||||
| knowledge about what sockets libcurl uses. | ||||
|  | ||||
| An application should call \fBcurl_multi_timeout(3)\fP to figure out how long | ||||
| it should wait for socket actions \- at most \- before doing the timeout | ||||
| action: call the \fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP | ||||
| argument set to CURL_SOCKET_TIMEOUT. | ||||
| Applications should call \fBcurl_multi_timeout(3)\fP to figure out how long to | ||||
| wait for socket actions \- at most \- before doing the timeout action: call | ||||
| the \fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP argument set to | ||||
| CURL_SOCKET_TIMEOUT. | ||||
|  | ||||
| .SH "CALLBACK DETAILS" | ||||
|  | ||||
| The socket \fBcallback\fP function uses a prototype like this | ||||
| .nf | ||||
|  | ||||
|      int curl_socket_callback(CURL *easy,      /* easy handle */ | ||||
|                               curl_socket_t s, /* socket */ | ||||
|                               int action,      /* see values below */ | ||||
|                               void *userp);    /* "private" pointer */ | ||||
|   int curl_socket_callback(CURL *easy,      /* easy handle */ | ||||
|                            curl_socket_t s, /* socket */ | ||||
|                            int action,      /* see values below */ | ||||
|                            void *userp,    /* private callback pointer */ | ||||
|                            void *socketp); /* private socket pointer */ | ||||
|  | ||||
| .fi | ||||
| The callback MUST return 0. | ||||
|  | ||||
| The \fIaction\fP (third) argument to the callback has one of five values: | ||||
| The \fIeasy\fP argument is a pointer to the easy handle that deals with this | ||||
| particular socket. Note that a single handle may work with several sockets | ||||
| simultaneously. | ||||
|  | ||||
| The \fIs\fP argument is the actual socket value as you use it within your | ||||
| system. | ||||
|  | ||||
| The \fIaction\fP argument to the callback has one of five values: | ||||
| .RS | ||||
| .IP "CURL_POLL_NONE (0)" | ||||
| register, not interested in readiness (yet) | ||||
| @@ -57,6 +78,15 @@ register, interested in both read and write readiness | ||||
| .IP "CURL_POLL_REMOVE (4)" | ||||
| deregister | ||||
| .RE | ||||
|  | ||||
| The \fIsocketp\fP argument is a private pointer you have previously set with | ||||
| \fIcurl_multi_assign(3)\fP to be associated with the \fIs\fP socket. If no | ||||
| pointer has been set, socketp will be NULL. This argument is of course a | ||||
| service to applications that want to keep certain data or structs that are | ||||
| strictly associated to the given socket. | ||||
|  | ||||
| The \fIuserp\fP argument is a private pointer you have previously set with | ||||
| \fIcurl_multi_setopt(3)\fP and the CURLMOPT_SOCKETDATA option. | ||||
| .SH "RETURN VALUE" | ||||
| CURLMcode type, general libcurl multi interface error code. | ||||
|  | ||||
| @@ -90,7 +120,7 @@ action. | ||||
|  | ||||
| 9. Go back to step 6. | ||||
| .SH AVAILABILITY | ||||
| This function was added in libcurl 7.16.0 | ||||
| This function was added in libcurl 7.15.4, although not deemed stable yet. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_multi_cleanup "(3), " curl_multi_init "(3), " | ||||
| .BR curl_multi_fdset "(3), " curl_multi_info_read "(3)" | ||||
|   | ||||
| @@ -30,7 +30,7 @@ Call \fBcurl_multi_timeout(3)\fP, then wait for action on the sockets. You | ||||
| figure out which sockets to wait for by calling \fBcurl_multi_fdset(3)\fP or | ||||
| by a previous call to \fBcurl_multi_socket(3)\fP. | ||||
| .SH AVAILABILITY | ||||
| This function was added in libcurl 7.16.0 | ||||
| This function was added in libcurl 7.15.4, although not deemed stable yet. | ||||
| .SH "SEE ALSO" | ||||
| .BR curl_multi_cleanup "(3), " curl_multi_init "(3), " | ||||
| .BR curl_multi_fdset "(3), " curl_multi_info_read "(3), " | ||||
|   | ||||
| @@ -42,7 +42,9 @@ be set to one of the values described below. | ||||
| Cookie data will be shared across the easy handles using this shared object. | ||||
| .IP CURL_LOCK_DATA_DNS | ||||
| Cached DNS hosts will be shared across the easy handles using this shared | ||||
| object. | ||||
| 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! | ||||
| .RE | ||||
| .IP CURLSHOPT_UNSHARE | ||||
| This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that | ||||
|   | ||||
| @@ -174,7 +174,7 @@ problem with the local client certificate | ||||
| .IP "CURLE_SSL_CIPHER (59)" | ||||
| couldn't use specified cipher | ||||
| .IP "CURLE_SSL_CACERT (60)" | ||||
| problem with the CA cert (path? access rights?)  | ||||
| peer certificate cannot be authenticated with known CA certificates | ||||
| .IP "CURLE_BAD_CONTENT_ENCODING (61)" | ||||
| Unrecognized transfer encoding | ||||
| .IP "CURLE_LDAP_INVALID_URL (62)" | ||||
| @@ -208,6 +208,8 @@ No such TFTP user | ||||
| Character conversion failed | ||||
| .IP "CURLE_CONV_REQD (76)" | ||||
| Caller must register conversion callbacks | ||||
| .IP "CURLE_SSL_CACERT_BADFILE (77)" | ||||
| Problem with reading the SSL CA cert (path? access rights?) | ||||
| .SH "CURLMcode" | ||||
| This is the generic return code used by functions in the libcurl multi | ||||
| interface. Also consider \fIcurl_multi_strerror(3)\fP. | ||||
| @@ -219,14 +221,16 @@ Things are fine. | ||||
| .IP "CURLM_BAD_HANDLE (1)" | ||||
| The passed-in handle is not a valid CURLM handle. | ||||
| .IP "CURLM_BAD_EASY_HANDLE (2)" | ||||
| An easy handle was not good/valid. | ||||
| An easy handle was not good/valid. It could mean that it isn't an easy handle | ||||
| at all, or possibly that the handle already is in used by this or another | ||||
| multi handle. | ||||
| .IP "CURLM_OUT_OF_MEMORY (3)" | ||||
| You are doomed. | ||||
| .IP "CURLM_INTERNAL_ERROR (4)" | ||||
| This can only be returned if libcurl bugs. Please report it to us! | ||||
| .IP "CURLM_BAD_SOCKET (5)" | ||||
| The passed-in socket is not a valid one that libcurl already knows about. | ||||
| (Added in 7.16.0) | ||||
| (Added in 7.15.4) | ||||
| .SH "CURLSHcode" | ||||
| The "share" interface will return a CURLSHcode to indicate when an error has | ||||
| occurred.  Also consider \fIcurl_share_strerror(3)\fP. | ||||
|   | ||||
| @@ -1,6 +1,25 @@ | ||||
| .\" You can view this file with: | ||||
| .\" nroff -man [file] | ||||
| .\" $Id$ | ||||
| .\" ************************************************************************** | ||||
| .\" *                                  _   _ ____  _ | ||||
| .\" *  Project                     ___| | | |  _ \| | | ||||
| .\" *                             / __| | | | |_) | | | ||||
| .\" *                            | (__| |_| |  _ <| |___ | ||||
| .\" *                             \___|\___/|_| \_\_____| | ||||
| .\" * | ||||
| .\" * Copyright (C) 1998 - 2006, 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. | ||||
| .\" * | ||||
| .\" * $Id$ | ||||
| .\" ************************************************************************** | ||||
| .\" | ||||
| .TH libcurl-multi 3 "13 Oct 2001" "libcurl 7.10.1" "libcurl multi interface" | ||||
| .SH NAME | ||||
| @@ -14,8 +33,8 @@ for an overview of the libcurl easy interface. | ||||
|  | ||||
| All functions in the multi interface are prefixed with curl_multi. | ||||
| .SH "OBJECTIVES" | ||||
| The multi interface introduces several new abilities that the easy interface | ||||
| refuses to offer. They are mainly: | ||||
| The multi interface offers several abilities that the easy interface doesn't. | ||||
| They are mainly: | ||||
|  | ||||
| 1. Enable a "pull" interface. The application that uses libcurl decides where | ||||
| and when to ask libcurl to get/send data. | ||||
| @@ -23,8 +42,8 @@ and when to ask libcurl to get/send data. | ||||
| 2. Enable multiple simultaneous transfers in the same thread without making it | ||||
| complicated for the application. | ||||
|  | ||||
| 3. Enable the application to select() on its own file descriptors and curl's | ||||
| file descriptors simultaneous easily. | ||||
| 3. Enable the application to wait for action on its own file descriptors and | ||||
| curl's file descriptors simultaneous easily. | ||||
| .SH "ONE MULTI HANDLE MANY EASY HANDLES" | ||||
| To use the multi interface, you must first create a 'multi handle' with | ||||
| \fIcurl_multi_init(3)\fP. This handle is then used as input to all further | ||||
|   | ||||
| @@ -212,7 +212,7 @@ opened for writing with the \fICURLOPT_WRITEDATA\fP option. | ||||
| Now, we need to take a step back and have a deep breath. Here's one of those | ||||
| rare platform-dependent nitpicks. Did you spot it? On some platforms[2], | ||||
| libcurl won't be able to operate on files opened by the program. Thus, if you | ||||
| use the default callback and pass in a an open file with | ||||
| use the default callback and pass in an open file with | ||||
| \fICURLOPT_WRITEDATA\fP, it will crash. You should therefore avoid this to | ||||
| make your program run fine virtually everywhere. | ||||
|  | ||||
|   | ||||
| @@ -10,8 +10,8 @@ specific man pages for each function mentioned in here. There are also the | ||||
| \fIlibcurl-share(3)\fP man page and the \fIlibcurl-tutorial(3)\fP man page for | ||||
| in-depth understanding on how to program with libcurl. | ||||
|  | ||||
| There are more than a twenty custom bindings available that bring libcurl | ||||
| access to your favourite language. Look elsewhere for documentation on those. | ||||
| There are more than thirty custom bindings available that bring libcurl access | ||||
| to your favourite language. Look elsewhere for documentation on those. | ||||
|  | ||||
| libcurl has a global constant environment that you must set up and | ||||
| maintain while using libcurl.  This essentially means you call | ||||
|   | ||||
							
								
								
									
										31
									
								
								hiper/STATUS
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								hiper/STATUS
									
									
									
									
									
								
							| @@ -267,3 +267,34 @@ April 20, 2006 | ||||
|  using the same socket. I've cleaned up and simplified code now to adjust to | ||||
|  this. | ||||
|  | ||||
| --------------------------------------------------------------------------- | ||||
|  | ||||
| July 9, 2006 | ||||
|  | ||||
|  TODO: We need to alter how we use c-ares for getting info about its sockets, | ||||
|  as c-ares now provides a callback approach very similar to how libcurl is | ||||
|  about to work. | ||||
|  | ||||
|  I'm adding a function called curl_multi_assign() that will set a private | ||||
|  pointer added to the internal libcurl hash table for the particular socket | ||||
|  passed in to this function: | ||||
|  | ||||
|  CURLMcode curl_multi_assign(CURLM *multi_handle, | ||||
|                              curl_socket_t sockfd, | ||||
|                              void *sockp); | ||||
|  | ||||
|  'sockp' being a custom pointer set by the application to be associated with | ||||
|  this socket. The socket has to be already existing and in-use by libcurl, | ||||
|  like having already called the callback telling about its existance. | ||||
|  | ||||
|  The set hashp pointer will then be passed on to the callback in upcoming | ||||
|  calls when this same socket is used (in the brand new 'socketp' argument). | ||||
|  | ||||
| --------------------------------------------------------------------------- | ||||
|  | ||||
| July 30, 2006 | ||||
|  | ||||
|  Shockingly stupid (of me not having realized this before), but we really need | ||||
|  to add a 'running_handles' argument to the curl_multi_socket() and | ||||
|  curl_multi_socket_all() prototypes so that the caller can get to know when | ||||
|  all the transfers are actually done! | ||||
|   | ||||
							
								
								
									
										432
									
								
								hiper/hipev.c
									
									
									
									
									
								
							
							
						
						
									
										432
									
								
								hiper/hipev.c
									
									
									
									
									
								
							| @@ -10,8 +10,7 @@ | ||||
|  * Connect N connections. Z are idle, and X are active. Transfer as fast as | ||||
|  * possible. | ||||
|  * | ||||
|  * Run for a specific amount of time (10 secs for now). Output detailed timing | ||||
|  * information. | ||||
|  * Output detailed timing information. | ||||
|  * | ||||
|  * Uses libevent. | ||||
|  * | ||||
| @@ -50,16 +49,6 @@ | ||||
|    when using asynch supported libcurl. */ | ||||
| #define IDLE_TIME 10 | ||||
|  | ||||
| struct ourfdset { | ||||
|   /* __fds_bits is what the Linux glibc headers use when they declare the | ||||
|      fd_set struct so by using this we can actually avoid the typecase for the | ||||
|      FD_SET() macro usage but it would hardly be portable */ | ||||
|   char __fds_bits[NCONNECTIONS/8]; | ||||
| }; | ||||
| #define FD2_ZERO(x) memset(x, 0, sizeof(struct ourfdset)) | ||||
|  | ||||
| typedef struct ourfdset fd2_set; | ||||
|  | ||||
| struct globalinfo { | ||||
|   size_t dlcounter; | ||||
| }; | ||||
| @@ -71,11 +60,10 @@ struct connection { | ||||
|   size_t dlcounter; | ||||
|   struct globalinfo *global; | ||||
|   char error[CURL_ERROR_SIZE]; | ||||
|   struct event ev[3]; /* maximum 3 events per handle NOTE: should this rather | ||||
|                          be a define in a public curl header file or possibly | ||||
|                          just documented somewhere or... ? */ | ||||
| }; | ||||
|  | ||||
| /* this is the struct associated with each file descriptor libcurl tells us | ||||
|    it is dealing with */ | ||||
| struct fdinfo { | ||||
|   /* create a link list of fdinfo structs */ | ||||
|   struct fdinfo *next; | ||||
| @@ -84,40 +72,85 @@ struct fdinfo { | ||||
|   CURL *easy; | ||||
|   int action; /* as set by libcurl */ | ||||
|   long timeout; /* as set by libcurl */ | ||||
|   struct event ev; /* */ | ||||
|   int evset; /* true if the 'ev' struct has been used in a event_set() call */ | ||||
|   CURLM *multi; /* pointer to the multi handle */ | ||||
|   int *running_handles; /* pointer to the running_handles counter */ | ||||
| }; | ||||
|  | ||||
| static struct fdinfo *allsocks; | ||||
|  | ||||
| static struct fdinfo *findsock(curl_socket_t s) | ||||
| { | ||||
|   /* return the struct for the given socket */ | ||||
|   struct fdinfo *fdp = allsocks; | ||||
| static int running_handles; | ||||
|  | ||||
|   while(fdp) { | ||||
|     if(fdp->sockfd == s) | ||||
|       break; | ||||
|     fdp = fdp->next; | ||||
| /* we have the timerevent global so that when the final socket-based event is | ||||
|    done, we can remove the timerevent as well */ | ||||
| static struct event timerevent; | ||||
|  | ||||
| static void update_timeout(CURLM *multi_handle); | ||||
|  | ||||
| /* called from libevent on action on a particular socket ("event") */ | ||||
| static void eventcallback(int fd, short type, void *userp) | ||||
| { | ||||
|   struct fdinfo *fdp = (struct fdinfo *)userp; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   fprintf(stderr, "EVENT callback type %d\n", type); | ||||
|  | ||||
|   /* tell libcurl to deal with the transfer associated with this socket */ | ||||
|   do { | ||||
|     rc = curl_multi_socket(fdp->multi, fd, fdp->running_handles); | ||||
|   } while (rc == CURLM_CALL_MULTI_PERFORM); | ||||
|  | ||||
|   if(rc) { | ||||
|     fprintf(stderr, "curl_multi_socket() returned %d\n", (int)rc); | ||||
|   } | ||||
|   return fdp; /* a struct pointer or NULL */ | ||||
|  | ||||
|   fprintf(stderr, "running_handles: %d\n", *fdp->running_handles); | ||||
|   if(!*fdp->running_handles) { | ||||
|     /* last transfer is complete, kill pending timeout */ | ||||
|     fprintf(stderr, "last transfer done, kill timeout\n"); | ||||
|     if(evtimer_pending(&timerevent, NULL)) | ||||
|       evtimer_del(&timerevent); | ||||
|   } | ||||
|   else | ||||
|     update_timeout(fdp->multi); | ||||
| } | ||||
|  | ||||
| static void remsock(curl_socket_t s) | ||||
| /* called from libevent when our timer event expires */ | ||||
| static void timercallback(int fd, short type, void *userp) | ||||
| { | ||||
|   struct fdinfo *fdp = allsocks; | ||||
|   (void)fd; /* not used for this */ | ||||
|   (void)type; /* ignored in here */ | ||||
|   CURLM *multi_handle = (CURLM *)userp; | ||||
|   int running_handles; | ||||
|   CURLMcode rc; | ||||
|  | ||||
|   while(fdp) { | ||||
|     if(fdp->sockfd == s) | ||||
|       break; | ||||
|     fdp = fdp->next; | ||||
|   } | ||||
|   if(!fdp) | ||||
|   fprintf(stderr, "EVENT timeout\n"); | ||||
|  | ||||
|   /* tell libcurl to deal with the transfer associated with this socket */ | ||||
|   do { | ||||
|     rc = curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT, | ||||
|                            &running_handles); | ||||
|   } while (rc == CURLM_CALL_MULTI_PERFORM); | ||||
|  | ||||
|   if(running_handles) | ||||
|     /* Get the current timeout value from libcurl and set a new timeout */ | ||||
|     update_timeout(multi_handle); | ||||
| } | ||||
|  | ||||
| static void remsock(struct fdinfo *f) | ||||
| { | ||||
|   if(!f) | ||||
|     /* did not find socket to remove! */ | ||||
|     return; | ||||
|  | ||||
|   if(fdp->prev) | ||||
|     fdp->prev->next = fdp->next; | ||||
|   if(fdp->next) | ||||
|     fdp->next->prev = fdp->prev; | ||||
|   if(f->evset) | ||||
|     event_del(&f->ev); | ||||
|  | ||||
|   if(f->prev) | ||||
|     f->prev->next = f->next; | ||||
|   if(f->next) | ||||
|     f->next->prev = f->prev; | ||||
|   else | ||||
|     /* this was the last entry */ | ||||
|     allsocks = NULL; | ||||
| @@ -129,12 +162,35 @@ static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy, | ||||
|   fdp->sockfd = s; | ||||
|   fdp->action = action; | ||||
|   fdp->easy = easy; | ||||
|  | ||||
|   if(fdp->evset) | ||||
|     /* first remove the existing event if the old setup was used */ | ||||
|     event_del(&fdp->ev); | ||||
|  | ||||
|   /* now use and add the current socket setup to libevent. The EV_PERSIST is | ||||
|      the key here as otherwise libevent will automatically remove the event | ||||
|      when it occurs the first time */ | ||||
|   event_set(&fdp->ev, fdp->sockfd, | ||||
|             (action&CURL_POLL_IN?EV_READ:0)| | ||||
|             (action&CURL_POLL_OUT?EV_WRITE:0)| EV_PERSIST, | ||||
|             eventcallback, fdp); | ||||
|  | ||||
|   fdp->evset=1; | ||||
|  | ||||
|   fprintf(stderr, "event_add() for fd %d\n", s); | ||||
|  | ||||
|   /* We don't use any socket-specific timeout but intead we use a single | ||||
|      global one. This is (mostly) because libcurl doesn't expose any | ||||
|      particular socket- based timeout value. */ | ||||
|   event_add(&fdp->ev, NULL); | ||||
| } | ||||
|  | ||||
| static void addsock(curl_socket_t s, CURL *easy, int action) | ||||
| static void addsock(curl_socket_t s, CURL *easy, int action, CURLM *multi) | ||||
| { | ||||
|   struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1); | ||||
|  | ||||
|   fdp->multi = multi; | ||||
|   fdp->running_handles = &running_handles; | ||||
|   setsock(fdp, s, easy, action); | ||||
|  | ||||
|   if(allsocks) { | ||||
| @@ -146,73 +202,49 @@ static void addsock(curl_socket_t s, CURL *easy, int action) | ||||
|   } | ||||
|   else | ||||
|     allsocks = fdp; | ||||
| } | ||||
|  | ||||
| static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd) | ||||
| { | ||||
|   struct fdinfo *fdp = allsocks; | ||||
|   int writable=0; | ||||
|  | ||||
|   FD2_ZERO(fdread); | ||||
|   FD2_ZERO(fdwrite); | ||||
|  | ||||
|   *maxfd = 0; | ||||
|  | ||||
| #if 0 | ||||
|   printf("Wait for: "); | ||||
| #endif | ||||
|  | ||||
|   while(fdp) { | ||||
|     if(fdp->action & CURL_POLL_IN) { | ||||
|       FD_SET(fdp->sockfd, (fd_set *)fdread); | ||||
|     } | ||||
|     if(fdp->action & CURL_POLL_OUT) { | ||||
|       FD_SET(fdp->sockfd, (fd_set *)fdwrite); | ||||
|       writable++; | ||||
|     } | ||||
|  | ||||
| #if 0 | ||||
|     printf("%d (%s%s) ", | ||||
|            fdp->sockfd, | ||||
|            (fdp->action & CURL_POLL_IN)?"r":"", | ||||
|            (fdp->action & CURL_POLL_OUT)?"w":""); | ||||
| #endif | ||||
|  | ||||
|     if(fdp->sockfd > *maxfd) | ||||
|       *maxfd = fdp->sockfd; | ||||
|  | ||||
|     fdp = fdp->next; | ||||
|   } | ||||
| #if 0 | ||||
|   if(writable) | ||||
|     printf("Check for %d writable sockets\n", writable); | ||||
| #endif | ||||
|   /* Set this association in libcurl */ | ||||
|   curl_multi_assign(multi, s, fdp); | ||||
| } | ||||
|  | ||||
| /* on port 8999 we run a fork enabled sws that supports 'idle' and 'stream' */ | ||||
| #define PORT "8999" | ||||
|  | ||||
| #define HOST "192.168.1.13" | ||||
| #define HOST "127.0.0.1" | ||||
|  | ||||
| #define URL_IDLE   "http://" HOST ":" PORT "/1000" | ||||
| #if 1 | ||||
| #define URL_ACTIVE "http://" HOST ":" PORT "/1001" | ||||
|  | ||||
| #else | ||||
| #define URL_ACTIVE "http://localhost/" | ||||
| #endif | ||||
|  | ||||
| static int socket_callback(CURL *easy,      /* easy handle */ | ||||
|                            curl_socket_t s, /* socket */ | ||||
|                            int what,        /* see above */ | ||||
|                            void *userp)     /* "private" pointer */ | ||||
|                            void *cbp,       /* callback pointer */ | ||||
|                            void *socketp)   /* socket pointer */ | ||||
| { | ||||
|   struct fdinfo *fdp; | ||||
|   printf("socket %d easy %p what %d\n", s, easy, what); | ||||
|   struct fdinfo *fdp = (struct fdinfo *)socketp; | ||||
|   char *whatstr[]={ | ||||
|     "none", | ||||
|     "IN", | ||||
|     "OUT", | ||||
|     "INOUT", | ||||
|     "REMOVE"}; | ||||
|  | ||||
|   fprintf(stderr, "socket %d easy %p what %s\n", s, easy, | ||||
|           whatstr[what]); | ||||
|  | ||||
|   if(what == CURL_POLL_REMOVE) | ||||
|     remsock(s); | ||||
|     remsock(fdp); | ||||
|   else { | ||||
|     fdp = findsock(s); | ||||
|  | ||||
|     if(!fdp) { | ||||
|       addsock(s, easy, what); | ||||
|       /* not previously known, add it and set association */ | ||||
|       printf("Add info for socket %d %s%s\n", s, | ||||
|              what&CURL_POLL_IN?"READ":"", | ||||
|              what&CURL_POLL_OUT?"WRITE":"" ); | ||||
|       addsock(s, easy, what, cbp); | ||||
|     } | ||||
|     else { | ||||
|       /* we already know about it, just change action/timeout */ | ||||
| @@ -230,137 +262,38 @@ writecallback(void *ptr, size_t size, size_t nmemb, void *data) | ||||
| { | ||||
|   size_t realsize = size * nmemb; | ||||
|   struct connection *c = (struct connection *)data; | ||||
|   (void)ptr; | ||||
|  | ||||
|   c->dlcounter += realsize; | ||||
|   c->global->dlcounter += realsize; | ||||
|  | ||||
| #if 0 | ||||
|   printf("%02d: %d, total %d\n", | ||||
|          c->id, c->dlcounter, c->global->dlcounter); | ||||
| #endif | ||||
|  | ||||
|   return realsize; | ||||
| } | ||||
|  | ||||
| /* return the diff between two timevals, in us */ | ||||
| static long tvdiff(struct timeval *newer, struct timeval *older) | ||||
| { | ||||
|   return (newer->tv_sec-older->tv_sec)*1000000+ | ||||
|     (newer->tv_usec-older->tv_usec); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* store the start time of the program in this variable */ | ||||
| static struct timeval timer; | ||||
|  | ||||
| static void timer_start(void) | ||||
| { | ||||
|   /* capture the time of the start moment */ | ||||
|   gettimeofday(&timer, NULL); | ||||
| } | ||||
|  | ||||
| static struct timeval cont; /* at this moment we continued */ | ||||
|  | ||||
| int still_running; /* keep number of running handles */ | ||||
|  | ||||
| struct conncount { | ||||
|   long time_us; | ||||
|   long laps; | ||||
|   long maxtime; | ||||
| }; | ||||
|  | ||||
| static struct timeval timerpause; | ||||
| static void timer_pause(void) | ||||
| { | ||||
|   /* capture the time of the pause moment */ | ||||
|   gettimeofday(&timerpause, NULL); | ||||
|  | ||||
|   /* If we have a previous continue (all times except the first), we can now | ||||
|      store the time for a whole "lap" */ | ||||
|   if(cont.tv_sec) { | ||||
|     long lap; | ||||
|  | ||||
|     lap = tvdiff(&timerpause, &cont); | ||||
|   } | ||||
| } | ||||
|  | ||||
| static long paused; /* amount of us we have been pausing */ | ||||
|  | ||||
| static void timer_continue(void) | ||||
| { | ||||
|   /* Capture the time of the restored operation moment, now calculate how long | ||||
|      time we were paused and added that to the 'paused' variable. | ||||
|    */ | ||||
|   gettimeofday(&cont, NULL); | ||||
|  | ||||
|   paused += tvdiff(&cont, &timerpause); | ||||
| } | ||||
|  | ||||
| static long total; /* amount of us from start to stop */ | ||||
| static void timer_total(void) | ||||
| { | ||||
|   struct timeval stop; | ||||
|   /* Capture the time of the operation stopped moment, now calculate how long | ||||
|      time we were running and how much of that pausing. | ||||
|    */ | ||||
|   gettimeofday(&stop, NULL); | ||||
|  | ||||
|   total = tvdiff(&stop, &timer); | ||||
| } | ||||
|  | ||||
| struct globalinfo info; | ||||
| struct connection *conns; | ||||
|  | ||||
| long selects; | ||||
| long timeouts; | ||||
|  | ||||
| long multi_socket; | ||||
| long performalive; | ||||
| long performselect; | ||||
| long topselect; | ||||
|  | ||||
| int num_total; | ||||
| int num_idle; | ||||
| int num_active; | ||||
|  | ||||
| static void report(void) | ||||
| static void update_timeout(CURLM *multi_handle) | ||||
| { | ||||
|   int i; | ||||
|   long active = total - paused; | ||||
|   long numdl = 0; | ||||
|   long timeout_ms; | ||||
|   struct timeval timeout; | ||||
|  | ||||
|   for(i=0; i < num_total; i++) { | ||||
|     if(conns[i].dlcounter) | ||||
|       numdl++; | ||||
|   } | ||||
|  | ||||
|   printf("Summary from %d simultanoues transfers (%d active)\n", | ||||
|          num_total, num_active); | ||||
|   printf("%d out of %d connections provided data\n", numdl, num_total); | ||||
|  | ||||
|   printf("Total time: %ldus paused: %ldus curl_multi_socket(): %ldus\n", | ||||
|          total, paused, active); | ||||
|  | ||||
|   printf("%d calls to select() " | ||||
|          "Average time: %dus\n", | ||||
|          selects, paused/selects); | ||||
|   printf(" Average number of readable connections per select() return: %d\n", | ||||
|          performselect/selects); | ||||
|  | ||||
|   printf(" Max number of readable connections for a single select() " | ||||
|          "return: %d\n", | ||||
|          topselect); | ||||
|  | ||||
|   printf("%ld calls to multi_socket(), " | ||||
|          "Average time: %ldus\n", | ||||
|          multi_socket, active/multi_socket); | ||||
|  | ||||
|   printf("%ld select() timeouts\n", timeouts); | ||||
|  | ||||
|   printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n", | ||||
|          info.dlcounter, | ||||
|          info.dlcounter/(total/1000000), | ||||
|          total/info.dlcounter); | ||||
|   /* Since we need a global timeout to occur after a given time of inactivity, | ||||
|      we use a single timeout-event. Get the timeout value from libcurl, and | ||||
|      update it after every call to libcurl. */ | ||||
|   curl_multi_timeout(multi_handle, &timeout_ms); | ||||
|  | ||||
|   /* convert ms to timeval */ | ||||
|   timeout.tv_sec = timeout_ms/1000; | ||||
|   timeout.tv_usec = (timeout_ms%1000)*1000; | ||||
|   evtimer_add(&timerevent, &timeout); | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| @@ -368,13 +301,7 @@ int main(int argc, char **argv) | ||||
|   CURLM *multi_handle; | ||||
|   CURLMsg *msg; | ||||
|   CURLcode code = CURLE_OK; | ||||
|   CURLMcode mcode = CURLM_OK; | ||||
|   int rc; | ||||
|   int i; | ||||
|   fd2_set fdsizecheck; | ||||
|   int selectmaxamount; | ||||
|   struct fdinfo *fdp; | ||||
|   char act; | ||||
|  | ||||
|   memset(&info, 0, sizeof(struct globalinfo)); | ||||
|  | ||||
| @@ -406,9 +333,11 @@ int main(int argc, char **argv) | ||||
|   /* init the multi stack */ | ||||
|   multi_handle = curl_multi_init(); | ||||
|  | ||||
|   /* initialize the timeout event */ | ||||
|   evtimer_set(&timerevent, timercallback, multi_handle); | ||||
|  | ||||
|   for(i=0; i< num_total; i++) { | ||||
|     CURL *e; | ||||
|     char *nl; | ||||
|  | ||||
|     memset(&conns[i], 0, sizeof(struct connection)); | ||||
|  | ||||
| @@ -443,88 +372,21 @@ int main(int argc, char **argv) | ||||
|   } | ||||
|  | ||||
|   curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback); | ||||
|   curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, NULL); | ||||
|   curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, multi_handle); | ||||
|  | ||||
|   /* we start the action by calling *socket() right away */ | ||||
|   while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle)); | ||||
|   /* we start the action by calling *socket_all() */ | ||||
|   while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle, | ||||
|                                                           &running_handles)); | ||||
|  | ||||
|   printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG); | ||||
|   timer_start(); | ||||
|   timer_pause(); | ||||
|   /* update timeout */ | ||||
|   update_timeout(multi_handle); | ||||
|  | ||||
|   while(1) { | ||||
|     struct timeval timeout; | ||||
|     int rc; /* select() return code */ | ||||
|     long timeout_ms; | ||||
|   /* event_dispatch() runs the event main loop. It ends when no events are | ||||
|      left to wait for. */ | ||||
|  | ||||
|     fd2_set fdread; | ||||
|     fd2_set fdwrite; | ||||
|     int maxfd; | ||||
|   event_dispatch(); | ||||
|  | ||||
|     curl_multi_timeout(multi_handle, &timeout_ms); | ||||
|  | ||||
|     /* set timeout to wait */ | ||||
|     timeout.tv_sec = timeout_ms/1000; | ||||
|     timeout.tv_usec = (timeout_ms%1000)*1000; | ||||
|  | ||||
|     /* convert file descriptors from the transfers to fd_sets */ | ||||
|     fdinfo2fdset(&fdread, &fdwrite, &maxfd); | ||||
|  | ||||
|     selects++; | ||||
|     rc = select(maxfd+1, | ||||
|                 (fd_set *)&fdread, | ||||
|                 (fd_set *)&fdwrite, | ||||
|                 NULL, &timeout); | ||||
|     switch(rc) { | ||||
|     case -1: | ||||
|       /* select error */ | ||||
|       break; | ||||
|     case 0: | ||||
|       timeouts++; | ||||
|       curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       /* timeout or readable/writable sockets */ | ||||
|  | ||||
|       for(i=0, fdp = allsocks; fdp; fdp = fdp->next) { | ||||
|         act = 0; | ||||
|         if((fdp->action & CURL_POLL_IN) && | ||||
|            FD_ISSET(fdp->sockfd, &fdread)) { | ||||
|           act |= CURL_POLL_IN; | ||||
|           i++; | ||||
|         } | ||||
|         if((fdp->action & CURL_POLL_OUT) && | ||||
|            FD_ISSET(fdp->sockfd, &fdwrite)) { | ||||
|           act |= CURL_POLL_OUT; | ||||
|           i++; | ||||
|         } | ||||
|  | ||||
|         if(act) { | ||||
|           multi_socket++; | ||||
|           timer_continue(); | ||||
|           if(act & CURL_POLL_OUT) | ||||
|             act--; | ||||
|           curl_multi_socket(multi_handle, fdp->sockfd); | ||||
|           timer_pause(); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       performselect += rc; | ||||
|       if(rc > topselect) | ||||
|         topselect = rc; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     timer_total(); /* calculate the total time spent so far */ | ||||
|  | ||||
|     if(total > RUN_FOR_THIS_LONG) { | ||||
|       printf("Stopped after %ldus\n", total); | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if(still_running != num_total) { | ||||
|   { | ||||
|     /* something made connections fail, extract the reason and tell */ | ||||
|     int msgs_left; | ||||
|     struct connection *cptr; | ||||
| @@ -532,10 +394,10 @@ int main(int argc, char **argv) | ||||
|       if (msg->msg == CURLMSG_DONE) { | ||||
|         curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr); | ||||
|  | ||||
|         printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error); | ||||
|         printf("%d => (%d) %s\n", | ||||
|                cptr->id, msg->data.result, cptr->error); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   curl_multi_cleanup(multi_handle); | ||||
| @@ -544,7 +406,5 @@ int main(int argc, char **argv) | ||||
|   for(i=0; i< num_total; i++) | ||||
|     curl_easy_cleanup(conns[i].e); | ||||
|  | ||||
|   report(); | ||||
|  | ||||
|   return code; | ||||
| } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user