Compare commits
	
		
			1679 Commits
		
	
	
		
			curl-7_16_
			...
			curl-7_19_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 6ebc2b2561 | ||
|   | 95b817e8d7 | ||
|   | 558f034007 | ||
|   | 72ea805298 | ||
|   | 79ffbf7fe1 | ||
|   | 4f0d286d2c | ||
|   | 6fb5888e55 | ||
|   | b5810dfe9d | ||
|   | 85a79f9d67 | ||
|   | d24465b79a | ||
|   | c67a99ff27 | ||
|   | bae4e12302 | ||
|   | 09df1cdb5c | ||
|   | 2946d87e48 | ||
|   | 6a2d7bff1a | ||
|   | 9b7b2b347f | ||
|   | 33638d5347 | ||
|   | 2ae7d2e6ea | ||
|   | ffc490ef89 | ||
|   | 29b75ca46f | ||
|   | 004dde18a7 | ||
|   | 3440e8d208 | ||
|   | e138ae5ec9 | ||
|   | bf8ba229e0 | ||
|   | 19d0a7495e | ||
|   | 099b62f124 | ||
|   | 8ce78ca488 | ||
|   | fc9610919c | ||
|   | e082d2403c | ||
|   | 370c3afc71 | ||
|   | 93357ef017 | ||
|   | 753592cc70 | ||
|   | b150e6866d | ||
|   | 2f475fa9ea | ||
|   | ecff50c2b4 | ||
|   | 6f53cf9cc6 | ||
|   | 1056202b48 | ||
|   | 709de3d621 | ||
|   | f9894f4ebc | ||
|   | 74d3b80d70 | ||
|   | 4b01dfe369 | ||
|   | fc09d10560 | ||
|   | 59b2e3ea4a | ||
|   | 243cf29793 | ||
|   | 9ded8fbe58 | ||
|   | 9258928c2d | ||
|   | 132cd3aa2c | ||
|   | fef60d9d41 | ||
|   | 2fdd24c724 | ||
|   | 852a02daff | ||
|   | 2a6148716c | ||
|   | 5ca692fc89 | ||
|   | 3e2487493e | ||
|   | fdcb0cd2bc | ||
|   | 4962e1772d | ||
|   | d7d5618498 | ||
|   | 3f3d6ebe66 | ||
|   | ec28988bfa | ||
|   | db23538898 | ||
|   | 423a18cecc | ||
|   | f164260eee | ||
|   | a091121293 | ||
|   | d744c85310 | ||
|   | c9f2c54c49 | ||
|   | f29d223ed5 | ||
|   | 8dabd34432 | ||
|   | a104a365e3 | ||
|   | 62d94ff342 | ||
|   | cbc04a7d40 | ||
|   | 71d3c5bf41 | ||
|   | bc69e46ad1 | ||
|   | 13f035b905 | ||
|   | 79cbe50894 | ||
|   | 1c04aa54a7 | ||
|   | b718283327 | ||
|   | b34390017b | ||
|   | 8980f89370 | ||
|   | f46d47239f | ||
|   | 13dc82b9d4 | ||
|   | a243dd4587 | ||
|   | 9d5d6c557b | ||
|   | a604682805 | ||
|   | 70b1cd798f | ||
|   | 578f42d588 | ||
|   | e3ad6d2bd1 | ||
|   | 4b64a8d20d | ||
|   | fcc8700218 | ||
|   | e5b713ee63 | ||
|   | 9849c6b847 | ||
|   | 9bb5da968c | ||
|   | d5a71fd567 | ||
|   | 0f98ba4729 | ||
|   | a6a2174bf7 | ||
|   | f07c3171e3 | ||
|   | 6cb1e3f3fa | ||
|   | 81b64f69a5 | ||
|   | 17e1f58fd6 | ||
|   | 582833b338 | ||
|   | 48be4fa069 | ||
|   | 2af05bdd3c | ||
|   | 4dbfc91e2b | ||
|   | 95cef39def | ||
|   | 00fb5bcf35 | ||
|   | 42eeb93d99 | ||
|   | afe7bb4b33 | ||
|   | 0f5f91df0b | ||
|   | f209a4804b | ||
|   | 5794ffe4bd | ||
|   | ceb49d3742 | ||
|   | 44142f8234 | ||
|   | 347213d124 | ||
|   | 8ca51bc68a | ||
|   | 56f852a64f | ||
|   | 1c68e79091 | ||
|   | 473a050f0b | ||
|   | 6768e81d5d | ||
|   | 3743f515cf | ||
|   | 3e0b6a7d1f | ||
|   | ef72f7d513 | ||
|   | 2f71461b29 | ||
|   | d8cab4c133 | ||
|   | 95a093e97b | ||
|   | 68bb51c55b | ||
|   | fb8fe6f2b3 | ||
|   | 3e61c90dbe | ||
|   | ac18b471d2 | ||
|   | bbe2386bff | ||
|   | 2f47248e3c | ||
|   | 315bb970a5 | ||
|   | 65b0f6049d | ||
|   | 0033535e21 | ||
|   | 3e4a8cb800 | ||
|   | ad638da2c2 | ||
|   | a923d8541c | ||
|   | 66fb9ca5f6 | ||
|   | 11cb78c5f8 | ||
|   | 527a5f0980 | ||
|   | 6e878d2ca4 | ||
|   | cf30b24706 | ||
|   | 709a2ed474 | ||
|   | ecd30cc8bb | ||
|   | 0105ad5e39 | ||
|   | cebaab8ee5 | ||
|   | 34281925d6 | ||
|   | e90c4fa770 | ||
|   | a06e077938 | ||
|   | 7bdae7be4f | ||
|   | c125d83e9e | ||
|   | 2abf9221e3 | ||
|   | 6f1e89085c | ||
|   | 5303cdc4af | ||
|   | feb03e4717 | ||
|   | 64e3a091c3 | ||
|   | a2c50a980c | ||
|   | 23478b891f | ||
|   | aab2d52b25 | ||
|   | 9a9041f1ce | ||
|   | 0aa704935b | ||
|   | ede7f8f5de | ||
|   | 3c317d2fac | ||
|   | b55b0258e0 | ||
|   | 55a8098d48 | ||
|   | 389e50ff1e | ||
|   | 1df4043ad7 | ||
|   | b000b8a736 | ||
|   | 7eab7fa353 | ||
|   | 58f7c82d52 | ||
|   | 4d1cd0da93 | ||
|   | 9ee7a014c9 | ||
|   | e1ab7db87d | ||
|   | 14a5596346 | ||
|   | 2eba5f33b9 | ||
|   | 60a3773c50 | ||
|   | e8e8177e9d | ||
|   | f1fe04245a | ||
|   | 8bb208e8f8 | ||
|   | f8a3aa91cd | ||
|   | 019bde82ce | ||
|   | ca5e38751c | ||
|   | b5b25b39e9 | ||
|   | 1784523cc6 | ||
|   | d71d10adbc | ||
|   | 40fb750589 | ||
|   | 62a6b8d4a6 | ||
|   | 24b1890710 | ||
|   | 3a1d28379a | ||
|   | c57285d199 | ||
|   | 68cfe929c4 | ||
|   | 6237fd2c16 | ||
|   | b023f9bd2a | ||
|   | b7ac885d38 | ||
|   | cbd9dcbe41 | ||
|   | 4594187732 | ||
|   | 63818f8488 | ||
|   | 8af61cdb66 | ||
|   | ab83c0fd5b | ||
|   | 3cc40a2584 | ||
|   | c11933b3fd | ||
|   | 4687699726 | ||
|   | 012dcb4893 | ||
|   | f01d18e4b9 | ||
|   | dabd3cd355 | ||
|   | fa001f27a5 | ||
|   | 40b2e06a7f | ||
|   | 8008499028 | ||
|   | 3ac6929919 | ||
|   | 8d36acd29b | ||
|   | e54209d643 | ||
|   | f6a958dc3a | ||
|   | 2548e7b23f | ||
|   | 97046a3548 | ||
|   | a7d52c414f | ||
|   | 479466a495 | ||
|   | fa2a8f6fb8 | ||
|   | ddfa33be79 | ||
|   | 25c76a760e | ||
|   | 14240e9e10 | ||
|   | a3045b4e49 | ||
|   | b0685b3576 | ||
|   | 138c57c76a | ||
|   | 182a415555 | ||
|   | 6e789fc516 | ||
|   | 09f278121e | ||
|   | ed50e3f1b4 | ||
|   | 3a499099af | ||
|   | 931fc45f05 | ||
|   | 6076c74041 | ||
|   | b4fdccf87a | ||
|   | 8d012181b0 | ||
|   | d6344d9b5f | ||
|   | cb9410ded2 | ||
|   | 6838fb32af | ||
|   | 74d77cb140 | ||
|   | 7ad3abfd05 | ||
|   | 7c6df7132e | ||
|   | f27299dc3b | ||
|   | 47724ef238 | ||
|   | 357389a905 | ||
|   | 42cabc14d4 | ||
|   | a948ca1669 | ||
|   | 9cef14dfb2 | ||
|   | 2d15d84a01 | ||
|   | 1035469662 | ||
|   | 296a6f7749 | ||
|   | 5cff8124b0 | ||
|   | 90e2510e2f | ||
|   | 9251dd7b24 | ||
|   | 3615063fbc | ||
|   | 09664f1ab8 | ||
|   | bdf1157d55 | ||
|   | b4a5ce89c2 | ||
|   | 660516914e | ||
|   | 4c1c479fcf | ||
|   | 309651dc82 | ||
|   | b13b9f3331 | ||
|   | 108e584983 | ||
|   | f3b4071209 | ||
|   | fe1d024351 | ||
|   | 0de08d418f | ||
|   | 109edaae6d | ||
|   | d69a630989 | ||
|   | 987b67bd2e | ||
|   | f4d56802f9 | ||
|   | 9dfd6eacf4 | ||
|   | 5aed78e183 | ||
|   | 011e5dd864 | ||
|   | ae654266df | ||
|   | 03986f1b8b | ||
|   | bc649593e4 | ||
|   | cc0285da7f | ||
|   | f3bc16f4f5 | ||
|   | 15f94858f2 | ||
|   | 5febd06c25 | ||
|   | 9eb7fe8ac0 | ||
|   | 1f26ea4a85 | ||
|   | 912c29fd8c | ||
|   | eea468918e | ||
|   | 537490e391 | ||
|   | de8e362d4a | ||
|   | 7a588144b7 | ||
|   | 7f2999aa43 | ||
|   | a3498f96ef | ||
|   | 637bfa0252 | ||
|   | 1c8f689ecb | ||
|   | 7a8b11d716 | ||
|   | a67e207866 | ||
|   | 5817209158 | ||
|   | b39d409aa2 | ||
|   | a18fb9448b | ||
|   | 1f3007dbb4 | ||
|   | 5dafa4a270 | ||
|   | e93bcbeee1 | ||
|   | adc032e7d8 | ||
|   | 248c2b9bf5 | ||
|   | a8baa05023 | ||
|   | 7066a79466 | ||
|   | 4a623f7ed2 | ||
|   | f18700ef64 | ||
|   | 52d9a3c34f | ||
|   | d785ed2588 | ||
|   | 4ff37a4ed1 | ||
|   | fe167b6ba2 | ||
|   | f042a7419d | ||
|   | bc0ebfcdeb | ||
|   | 57d13c770a | ||
|   | 1692384636 | ||
|   | 7634091325 | ||
|   | bdc8f59c17 | ||
|   | 817efbc29c | ||
|   | d2661cb4b2 | ||
|   | 9b0110f50c | ||
|   | 5876381f86 | ||
|   | c4edc25d01 | ||
|   | 36361d14cf | ||
|   | c8fe5f485c | ||
|   | 1ac1212925 | ||
|   | 3d4fb5136d | ||
|   | b6b03c8ab9 | ||
|   | 432945e422 | ||
|   | 052f9ddedb | ||
|   | a96784b98e | ||
|   | e06944438a | ||
|   | fa1009b6fc | ||
|   | b377e857bd | ||
|   | 9a806f667b | ||
|   | 979c9ce8e3 | ||
|   | b217e6eed7 | ||
|   | 6b7e74a030 | ||
|   | 7fdeb14e6d | ||
|   | 8a323f8354 | ||
|   | a7abd5bf70 | ||
|   | 932b589780 | ||
|   | 27c282a6ee | ||
|   | 5373289574 | ||
|   | 7d0eabaa80 | ||
|   | e7f5d12cb6 | ||
|   | f14e020370 | ||
|   | e933b28aaf | ||
|   | 1bc490077a | ||
|   | 7d773abe50 | ||
|   | f22114aeed | ||
|   | 0919de4511 | ||
|   | 3e5292a052 | ||
|   | 2066d60b16 | ||
|   | 51e84c77e7 | ||
|   | 775d9e0615 | ||
|   | a20d55fb64 | ||
|   | 1b37baf656 | ||
|   | bffe69a151 | ||
|   | 71525352f0 | ||
|   | facc5f7ec5 | ||
|   | 184229b1e5 | ||
|   | 3e488c4f19 | ||
|   | 3f84e373ac | ||
|   | ac6d6ec2f1 | ||
|   | f11d5d9de8 | ||
|   | ed2dbefa73 | ||
|   | 39f23aec6b | ||
|   | 362422641e | ||
|   | a9dc900515 | ||
|   | 3a705696af | ||
|   | 2cfb8a2bf0 | ||
|   | 21ee1c2d01 | ||
|   | a00febe1a0 | ||
|   | 1e7125ae7b | ||
|   | aa4a7471dd | ||
|   | 69a03ce23c | ||
|   | 0f50cd7623 | ||
|   | 669c555874 | ||
|   | 1cfb73a129 | ||
|   | 2a585c2fba | ||
|   | 32a83128e6 | ||
|   | fe7bb33af8 | ||
|   | da6fa34f02 | ||
|   | 37a358ab93 | ||
|   | 3452c8d693 | ||
|   | 336992cc54 | ||
|   | 13afcbd1eb | ||
|   | e58a3fd0aa | ||
|   | 57625b6c4c | ||
|   | 0d058d2174 | ||
|   | 8d49a8f278 | ||
|   | b4b6cfdb1c | ||
|   | 6b7ccde156 | ||
|   | 9b0fd007fd | ||
|   | 6f3ef94836 | ||
|   | 08ac9866e0 | ||
|   | a17fadea3a | ||
|   | e30bbfd85d | ||
|   | 120f9d81b2 | ||
|   | fa38839a80 | ||
|   | d8f109176c | ||
|   | bbb1b99ce1 | ||
|   | 0cd8840dba | ||
|   | d4b253ba3e | ||
|   | aee7fc118b | ||
|   | 60f0b4fffe | ||
|   | a95e600eb0 | ||
|   | a25959184e | ||
|   | 0e5da5b8bc | ||
|   | ddfa4b8896 | ||
|   | d816a11bca | ||
|   | 7820391cb9 | ||
|   | 148866bc73 | ||
|   | 0b57c47547 | ||
|   | 02db4450df | ||
|   | ed7af82bdf | ||
|   | e3b5673e98 | ||
|   | 82412f218f | ||
|   | 7c648782bc | ||
|   | ee64d14733 | ||
|   | bfaab6ed6b | ||
|   | 97333deb3f | ||
|   | 400d9d4205 | ||
|   | ad1145a201 | ||
|   | 513c22df3b | ||
|   | b5afd53138 | ||
|   | 72b4b3c7f8 | ||
|   | eb60ba23f5 | ||
|   | 69aac49f79 | ||
|   | 67f139e016 | ||
|   | 654f047302 | ||
|   | e6c23672b2 | ||
|   | 1058e5fdde | ||
|   | 6929d9355f | ||
|   | 8c377ad965 | ||
|   | a81a16beac | ||
|   | d92945bb8a | ||
|   | 90a6a59a2f | ||
|   | 8bae3d9007 | ||
|   | 98042b858d | ||
|   | a837bd08b0 | ||
|   | 2c61e9c76a | ||
|   | da97f78ae0 | ||
|   | 2e1a9da5e2 | ||
|   | 422fd933f5 | ||
|   | 2594124825 | ||
|   | d09b6ecaa5 | ||
|   | fb2e71b9bd | ||
|   | 68b67e24f2 | ||
|   | c1e2341f0a | ||
|   | 70d834c512 | ||
|   | 65ee4e4555 | ||
|   | 5304b13365 | ||
|   | e547bfa933 | ||
|   | 36ddb13d1f | ||
|   | 74e3def5b3 | ||
|   | 24d41452b0 | ||
|   | 2597020d22 | ||
|   | 2d0fea2650 | ||
|   | c1a71ad14f | ||
|   | 024c7641a9 | ||
|   | 5c56bdf229 | ||
|   | af779fa57c | ||
|   | 9918541795 | ||
|   | 04d5c8fb77 | ||
|   | 5980b3cbb0 | ||
|   | 10074bfcc6 | ||
|   | 3940e69c91 | ||
|   | 0ace5f6553 | ||
|   | b8a9f19515 | ||
|   | 6cd007838d | ||
|   | 72870e2c57 | ||
|   | 9c8997cbe4 | ||
|   | c6efb82526 | ||
|   | 5abfdc0140 | ||
|   | d8bc4a0e9a | ||
|   | 8ad2fdd71e | ||
|   | a2e45a2211 | ||
|   | 621c2b9015 | ||
|   | b39d1e9b9d | ||
|   | e1c456407e | ||
|   | 3fe8251dfb | ||
|   | 930a45e7a9 | ||
|   | afc66554d7 | ||
|   | 998ab15570 | ||
|   | c0d258ca17 | ||
|   | 230e4547e8 | ||
|   | 4cf33909ee | ||
|   | 323273382c | ||
|   | 6f0a2608b4 | ||
|   | ea86edbd82 | ||
|   | e7b5a8e6cb | ||
|   | 27eaf0cf02 | ||
|   | c84904d8c8 | ||
|   | 01e1c85304 | ||
|   | 4774582dfb | ||
|   | 1ed09ff7a4 | ||
|   | d89cf27d65 | ||
|   | 35d5ba2626 | ||
|   | e5f0c38fa9 | ||
|   | 47925f3dd7 | ||
|   | 82c5950c7e | ||
|   | 1806879bb2 | ||
|   | 998b046d70 | ||
|   | ec4f6e93c2 | ||
|   | b49dcfb52b | ||
|   | c62d55342d | ||
|   | f7815fa93c | ||
|   | 6e305e11e3 | ||
|   | b97606f0b0 | ||
|   | f26154bfa9 | ||
|   | d220ac8582 | ||
|   | c57e748107 | ||
|   | d6f8f16068 | ||
|   | 466429efb0 | ||
|   | 89977c73d1 | ||
|   | a9a05a32bd | ||
|   | 2045c79e37 | ||
|   | e60b5245d3 | ||
|   | 90bbabce56 | ||
|   | ddfbe8b649 | ||
|   | d001f6a396 | ||
|   | d31da176eb | ||
|   | e664cd5826 | ||
|   | b8abeab6d3 | ||
|   | 4aa176c127 | ||
|   | 498e939f0e | ||
|   | 9a22b893b6 | ||
|   | 76d0d40946 | ||
|   | 791ad1210e | ||
|   | 100945694a | ||
|   | abe2e6ecf7 | ||
|   | d8efc99217 | ||
|   | 0163b5b8be | ||
|   | baee3996ab | ||
|   | 8ad1928d93 | ||
|   | 24bf52bc69 | ||
|   | 862049c490 | ||
|   | a8fc98aa30 | ||
|   | d70f33748c | ||
|   | b006c31b7b | ||
|   | ae45a462e0 | ||
|   | 3cb0dd6685 | ||
|   | c2a84aa6f0 | ||
|   | 9346e55d5a | ||
|   | 8fc2f8ef62 | ||
|   | 512b9ac194 | ||
|   | 560a82aeaf | ||
|   | 7358db5c27 | ||
|   | e059efda1b | ||
|   | 164a985115 | ||
|   | ade57a781c | ||
|   | 9f12ed83f2 | ||
|   | 8aabd9839b | ||
|   | 882fbb0433 | ||
|   | 15eee5dbbb | ||
|   | cfc1d037ff | ||
|   | c24ed07596 | ||
|   | 08aab6a620 | ||
|   | 2748c64d60 | ||
|   | c4f1ab3cc5 | ||
|   | 5e06ec8409 | ||
|   | 04d0a84ae5 | ||
|   | c1dfe2c529 | ||
|   | 7f88e8badb | ||
|   | 2f66ff2e4f | ||
|   | 76c251513e | ||
|   | 80afddacc8 | ||
|   | 7543c9df50 | ||
|   | 83fb13329d | ||
|   | e06c923605 | ||
|   | ab1169895f | ||
|   | 01e81c7e10 | ||
|   | 7bf1142ae0 | ||
|   | af9f7a952b | ||
|   | 514592b892 | ||
|   | d72efff878 | ||
|   | e4c60e2030 | ||
|   | ed80eb5b0f | ||
|   | 60dd765b3d | ||
|   | b380dd030f | ||
|   | 19479ea021 | ||
|   | d708ef6731 | ||
|   | d1238baecb | ||
|   | 0510759bc4 | ||
|   | 6d5cca5ed0 | ||
|   | e2b82b4325 | ||
|   | cf4570a06f | ||
|   | 6df5dddd90 | ||
|   | d4e9b141db | ||
|   | ec0665a931 | ||
|   | 836fa69e2e | ||
|   | 9026dc2da4 | ||
|   | 98c9af4c59 | ||
|   | e481d679b2 | ||
|   | eb68aa38e3 | ||
|   | 082237e2b5 | ||
|   | dd08a7a4f6 | ||
|   | a60c9ef88e | ||
|   | 4e3d235e04 | ||
|   | 19da3606f9 | ||
|   | fc9e0d2249 | ||
|   | 21a0f09081 | ||
|   | b84b71f524 | ||
|   | 3d29bda9f8 | ||
|   | 459c664043 | ||
|   | 45edad84cb | ||
|   | fd31f7e7e5 | ||
|   | 7b2531da24 | ||
|   | 848a13654d | ||
|   | 1cca8f5a30 | ||
|   | 12ffcf0b45 | ||
|   | 852989856d | ||
|   | 7dfdbf8fbe | ||
|   | 1eebb90030 | ||
|   | ab71654078 | ||
|   | 7a6cff4b3a | ||
|   | c3ba2198b1 | ||
|   | ff748f1a41 | ||
|   | b8193b6321 | ||
|   | 113d0937de | ||
|   | d0a506661f | ||
|   | 4e71173928 | ||
|   | e0f0a2ccee | ||
|   | 96edebf4d9 | ||
|   | 3783b455c0 | ||
|   | 7ee5238f5e | ||
|   | b398169567 | ||
|   | 1960eebc2d | ||
|   | ad1dd08693 | ||
|   | 95fd093c4a | ||
|   | ed1ad28e29 | ||
|   | 7076505c24 | ||
|   | 5825cf9457 | ||
|   | ff40415aee | ||
|   | f48eb36f75 | ||
|   | 768e3e796e | ||
|   | 3869d4a3a7 | ||
|   | a87c468c5c | ||
|   | 7abf50a5c0 | ||
|   | d3f46eb61b | ||
|   | 72c58b0d1d | ||
|   | 6c89e1b311 | ||
|   | 09777a4fc2 | ||
|   | 0331071346 | ||
|   | 614ae7b2bc | ||
|   | af41ada7aa | ||
|   | 6a33a4456e | ||
|   | e0c2a39ad4 | ||
|   | cda1f2be58 | ||
|   | 79e06c4147 | ||
|   | ead2618c31 | ||
|   | 84eb9fee76 | ||
|   | 79300cdcd9 | ||
|   | a9591ad1b7 | ||
|   | 098106b54c | ||
|   | 74bb59fa57 | ||
|   | c97d112b30 | ||
|   | 2dc20b84c1 | ||
|   | 39b689f966 | ||
|   | 6fd3ff4032 | ||
|   | ab8d1464a7 | ||
|   | bf90d11a31 | ||
|   | a08b6ae813 | ||
|   | 74c500b6ec | ||
|   | 26aeadbc3e | ||
|   | d0a4b50e19 | ||
|   | ebaf06a741 | ||
|   | 34d837c2dd | ||
|   | 7607d5145b | ||
|   | 12a90289ed | ||
|   | 592697583d | ||
|   | b50a96982e | ||
|   | aa2a54c10a | ||
|   | 532d4b5106 | ||
|   | 5788719988 | ||
|   | ac0b911eda | ||
|   | 10232bfe9e | ||
|   | a9c1ca9fc5 | ||
|   | d051dd8087 | ||
|   | bf52cef16f | ||
|   | 16a9c5e02b | ||
|   | fef1a90938 | ||
|   | 27870d48ff | ||
|   | 2f66f3ce08 | ||
|   | 369df58a0d | ||
|   | 3d08b352a2 | ||
|   | d13be06aaa | ||
|   | f1c69192da | ||
|   | a2314225e0 | ||
|   | 1e482fe6a8 | ||
|   | 80e7f9b9de | ||
|   | d219269f1b | ||
|   | 0ff0512aff | ||
|   | bdd731177e | ||
|   | abd1c526f0 | ||
|   | a050a5fa9b | ||
|   | 7f7b643c0d | ||
|   | cd2814725a | ||
|   | 342fa1cf06 | ||
|   | b425e851fb | ||
|   | 7c6a026230 | ||
|   | 2c9763da3e | ||
|   | a782c3e368 | ||
|   | 95bd901efe | ||
|   | 98c9a5b7f6 | ||
|   | 516192e7f2 | ||
|   | c37cdbe2cf | ||
|   | c0a30b04c2 | ||
|   | 86cbb23282 | ||
|   | e9a460411f | ||
|   | a57098ea9b | ||
|   | 6f3166c15b | ||
|   | 1380c9af9f | ||
|   | 942daece00 | ||
|   | 040a4443a1 | ||
|   | 641d5c4111 | ||
|   | ad4a9955c5 | ||
|   | 553ed99e3b | ||
|   | b74cdee6ab | ||
|   | f3c0afa5b8 | ||
|   | a69ba639ba | ||
|   | fc9ad03e66 | ||
|   | b9d66dca51 | ||
|   | ecf1c6ca5d | ||
|   | 9b48991ebd | ||
|   | 7a8a20416f | ||
|   | 458925ae0b | ||
|   | e44dc92197 | ||
|   | 9bb51d767e | ||
|   | 82e095a275 | ||
|   | 0e40261a11 | ||
|   | 8e9e33ae52 | ||
|   | 40e1a016f9 | ||
|   | 1cf559492a | ||
|   | 4957a838ef | ||
|   | 91aeebed26 | ||
|   | b16ea66cec | ||
|   | 80cec5a62a | ||
|   | 6c2c281a7e | ||
|   | 0836893335 | ||
|   | 590f0358d8 | ||
|   | 115446be37 | ||
|   | d83606ee3a | ||
|   | 8f4fda1d6f | ||
|   | 18cbb4d7d6 | ||
|   | 22e84d92b7 | ||
|   | 3d74649908 | ||
|   | ed63d9d4de | ||
|   | 8adc7038fe | ||
|   | b12fef3f31 | ||
|   | 6cc8df95dd | ||
|   | f105e23444 | ||
|   | 7513d29a48 | ||
|   | 97a41f3646 | ||
|   | 84de433e62 | ||
|   | 724ad15dad | ||
|   | 79aa6c841e | ||
|   | 058e764af8 | ||
|   | 0d09f342c4 | ||
|   | 9682c2037e | ||
|   | 74241e7d85 | ||
|   | 3154f04fb9 | ||
|   | 6982ed4db7 | ||
|   | 9dd3e4d481 | ||
|   | 1d95109ffa | ||
|   | e9bb7b7712 | ||
|   | 5e9c564883 | ||
|   | 3bb4602227 | ||
|   | 064eebeaf1 | ||
|   | 4ae644e427 | ||
|   | d208e56b16 | ||
|   | e6170eb20d | ||
|   | 2c80bcbc81 | ||
|   | b60dbfa9e9 | ||
|   | 9019fc5671 | ||
|   | 5db0f70491 | ||
|   | 53a549000c | ||
|   | 55700cb01f | ||
|   | f9a6062081 | ||
|   | 0cae201044 | ||
|   | 9df37b93df | ||
|   | 7b5c86033a | ||
|   | ade0890746 | ||
|   | 7a5596bf02 | ||
|   | d2125cf501 | ||
|   | c9eb41c056 | ||
|   | 0d722204c3 | ||
|   | e829d5643f | ||
|   | 1093287494 | ||
|   | 6398f71cc4 | ||
|   | e2b50b203d | ||
|   | ab0de23d83 | ||
|   | ec54fbd9ed | ||
|   | 074bd2a19b | ||
|   | fb23b85770 | ||
|   | 3458ce9ae5 | ||
|   | ba3e7a8656 | ||
|   | 240bae4eb2 | ||
|   | 4180ca7638 | ||
|   | 0e73361a06 | ||
|   | 23547fa2a0 | ||
|   | 550d6f74b9 | ||
|   | f7b71c2abe | ||
|   | 0da90b5d91 | ||
|   | f20c94ced9 | ||
|   | 3e635a2334 | ||
|   | e78652d850 | ||
|   | 48918c3047 | ||
|   | dc42d6fb8d | ||
|   | d2ad98d8c5 | ||
|   | d25aab2704 | ||
|   | cfaf88aab4 | ||
|   | ecc75be6f3 | ||
|   | 13ebf61850 | ||
|   | b3fafe9b3a | ||
|   | c66943bd89 | ||
|   | 11fae450fa | ||
|   | cf9259dd92 | ||
|   | 6634e3c3a3 | ||
|   | 533ae704a1 | ||
|   | fcc320ee40 | ||
|   | dc9fe9c361 | ||
|   | 75c369dcca | ||
|   | 019f6a1926 | ||
|   | 44fba11b34 | ||
|   | df07c87b89 | ||
|   | 8f9e0357dd | ||
|   | 736af32b49 | ||
|   | 6942d313ff | ||
|   | 940c075bd8 | ||
|   | 08e5c0812f | ||
|   | a8c71961e0 | ||
|   | d6f47cc60c | ||
|   | 63d595a047 | ||
|   | 15e56c3284 | ||
|   | fc1443dcfc | ||
|   | 59e3651af3 | ||
|   | 4c841a1f0c | ||
|   | 339ebdf08b | ||
|   | f01d324c83 | ||
|   | 405e192b8c | ||
|   | 1a340de0e5 | ||
|   | 05c191199d | ||
|   | 1fd7085ef1 | ||
|   | c3a7a757f7 | ||
|   | dca46e6470 | ||
|   | 7edd13822c | ||
|   | a2bff51ede | ||
|   | 5dc1240c49 | ||
|   | c764331dd9 | ||
|   | 586444b6b8 | ||
|   | ce1649564c | ||
|   | d76a74cc5e | ||
|   | 1b701c746f | ||
|   | 15bf168527 | ||
|   | 20e9fc73e2 | ||
|   | bad6410d08 | ||
|   | fecb67b246 | ||
|   | 2c0956200f | ||
|   | acd9d72466 | ||
|   | cd63a461d7 | ||
|   | 7bd098f670 | ||
|   | 4b5c504bd4 | ||
|   | ffae4f6b48 | ||
|   | 454e840590 | ||
|   | ed0a413711 | ||
|   | ff812ccdc9 | ||
|   | 03bbf4de48 | ||
|   | a62e155ca4 | ||
|   | b620e62f0f | ||
|   | b3186dee17 | ||
|   | ea3f63281c | ||
|   | 7b9435890d | ||
|   | 1bfbd25027 | ||
|   | ceb5a8ca7b | ||
|   | ddc98c6fc9 | ||
|   | ff6ff66e50 | ||
|   | a7b98f5f6b | ||
|   | 6bae091c1b | ||
|   | 33d68653f0 | ||
|   | 267836e83c | ||
|   | 87fdfe770d | ||
|   | 8fca5c2e69 | ||
|   | 5f2055729e | ||
|   | c6df788866 | ||
|   | e67b2524d1 | ||
|   | d7bcc26179 | ||
|   | 69e540dfa6 | ||
|   | 2198869eb1 | ||
|   | fb07259e0d | ||
|   | 9d28a0252c | ||
|   | d54c14ccf9 | ||
|   | 41def4be6e | ||
|   | 2d38d0d515 | ||
|   | e796c79d18 | ||
|   | c93ba48da2 | ||
|   | e322513698 | ||
|   | 6fa72e6417 | ||
|   | c914e6ea5d | ||
|   | 79cb74f03a | ||
|   | 34cf35051a | ||
|   | 9bd28a021f | ||
|   | 5ee3f41e0d | ||
|   | 64e88ff6a7 | ||
|   | acd7c94598 | ||
|   | bdb2beb8e4 | ||
|   | 727e23322f | ||
|   | ef0ed9b720 | ||
|   | a674654f83 | ||
|   | 3caeb0a91f | ||
|   | a4eddf0d0d | ||
|   | fcf9029179 | ||
|   | e40327ba00 | ||
|   | bdd0e3d3f5 | ||
|   | e9490fdbd9 | ||
|   | bd40b3ff3f | ||
|   | 8c66811e09 | ||
|   | daadcfd1de | ||
|   | 62df0ff025 | ||
|   | 01d95b56a0 | ||
|   | f6adae8d35 | ||
|   | bcaadb4284 | ||
|   | 8d963aa0e2 | ||
|   | 0530b0a5ca | ||
|   | 5396121595 | ||
|   | bcfc7d90d1 | ||
|   | 47246eb401 | ||
|   | 3620e71010 | ||
|   | c522f349fe | ||
|   | 6893fcaa9b | ||
|   | 301ae1ae1b | ||
|   | ddaa78f08b | ||
|   | 3d55877764 | ||
|   | 3ee32d7920 | ||
|   | b3de497d83 | ||
|   | ed6466d176 | ||
|   | 991505e077 | ||
|   | 56f17d2c9f | ||
|   | 19ae96f4d0 | ||
|   | 53108806af | ||
|   | 1d620a3df4 | ||
|   | 69f685056d | ||
|   | 9c7d4394f9 | ||
|   | bcc3c9279a | ||
|   | 5d63404966 | ||
|   | a8ae8087c4 | ||
|   | 502da27d65 | ||
|   | 4ab8ebb232 | ||
|   | f866af912d | ||
|   | 4f00a8db73 | ||
|   | 5004529685 | ||
|   | 2b63eb8511 | ||
|   | f09fe4b49f | ||
|   | 22c76df44d | ||
|   | 35be09cf58 | ||
|   | 3564aec388 | ||
|   | a042090467 | ||
|   | 148d727525 | ||
|   | 08adf67969 | ||
|   | e2c817731a | ||
|   | 8df7e0bdba | ||
|   | 14ff7e75e0 | ||
|   | d270d6518a | ||
|   | 18faa50940 | ||
|   | 0ce484eed9 | ||
|   | bce5ae9a07 | ||
|   | 15f832d1c2 | ||
|   | c249a8aa1b | ||
|   | fc794ae012 | ||
|   | 07227e8089 | ||
|   | 32cc75d6cb | ||
|   | 1c0a19ad53 | ||
|   | de23b98522 | ||
|   | 5e1c9e90d9 | ||
|   | 59b4bdf78d | ||
|   | 34d02d1969 | ||
|   | 2408b236ca | ||
|   | 4acd437952 | ||
|   | 314f62958d | ||
|   | c616d56e96 | ||
|   | f111c9edae | ||
|   | 7138296633 | ||
|   | 195e94c0fa | ||
|   | cadd08f36a | ||
|   | 7306b7829b | ||
|   | 423309541a | ||
|   | 9c6533d287 | ||
|   | b430576436 | ||
|   | 65008a4e55 | ||
|   | 3df484088f | ||
|   | 2912189875 | ||
|   | fcb2595ed6 | ||
|   | 0878af3ec0 | ||
|   | fe0d7aee49 | ||
|   | 2e42b0a252 | ||
|   | fcc485092a | ||
|   | a4945fe687 | ||
|   | 88d89b2177 | ||
|   | 61a2d5ea75 | ||
|   | c479c64333 | ||
|   | 7a2177dc42 | ||
|   | bf6e2f28ba | ||
|   | f5da1e5484 | ||
|   | fd8d862c37 | ||
|   | 083d3190e5 | ||
|   | 6787d1ed35 | ||
|   | d9023c16ab | ||
|   | 193d33fd4a | ||
|   | a46b40b7fd | ||
|   | 0b9b8acb08 | ||
|   | bf98b635cd | ||
|   | 7795eb6db8 | ||
|   | 31674559d3 | ||
|   | 04e4d9a0b3 | ||
|   | f277124a0f | ||
|   | 6adf5880f5 | ||
|   | 4e8c4fc80b | ||
|   | fc1d1ea934 | ||
|   | 9cd30c2012 | ||
|   | d639ed1aaf | ||
|   | c3a02f5407 | ||
|   | 674845f239 | ||
|   | 07a1857d59 | ||
|   | f4ffa85f60 | ||
|   | bcd7d03b3b | ||
|   | 82c9379b6c | ||
|   | c1730dc50a | ||
|   | 20695098c8 | ||
|   | ee52ae001c | ||
|   | 26115aac5d | ||
|   | ca6b27aed2 | ||
|   | 4fabe22173 | ||
|   | 7b1a22147e | ||
|   | dc24540ed1 | ||
|   | 92eae30f4d | ||
|   | 79ef08f631 | ||
|   | e3c5f8374b | ||
|   | 6dc68b4193 | ||
|   | afab4d888f | ||
|   | c751dfd65d | ||
|   | dbca1347f1 | ||
|   | 3b6315ce1f | ||
|   | 3c1db5f250 | ||
|   | 562e9b7bf3 | ||
|   | a83e72692f | ||
|   | bd99a7dc8c | ||
|   | db2d52a792 | ||
|   | 24602edc17 | ||
|   | b0b40d9a00 | ||
|   | 71b105ceb1 | ||
|   | ccb4956145 | ||
|   | 3d09cb0a88 | ||
|   | a03c2d825b | ||
|   | 06fb242e23 | ||
|   | a086952244 | ||
|   | 2b314064ae | ||
|   | 439990be88 | ||
|   | 41d8186c7e | ||
|   | 6e9276229f | ||
|   | 636f5eb882 | ||
|   | 963ef5414c | ||
|   | 975812d246 | ||
|   | 089668ec73 | ||
|   | cc0ce38acc | ||
|   | 8cdff55b80 | ||
|   | 662bee7193 | ||
|   | f8172f85b1 | ||
|   | 7d3ea12b62 | ||
|   | 59dc9085d1 | ||
|   | 4e4f33a297 | ||
|   | 8fa599215b | ||
|   | 31e2409d6b | ||
|   | 15c304225f | ||
|   | e1998e3b58 | ||
|   | 5c447f2499 | ||
|   | 9d0ffb9cc6 | ||
|   | 2be50baf97 | ||
|   | a1772ca406 | ||
|   | 30eda92a53 | ||
|   | 1f058f1014 | ||
|   | 84d0477cb9 | ||
|   | 1c93e75375 | ||
|   | 380ed8bebf | ||
|   | 98e8978857 | ||
|   | 56ddfbea6e | ||
|   | 45a2240ead | ||
|   | f75ba55b51 | ||
|   | 46e6115d72 | ||
|   | 800a72878a | ||
|   | 649f7b7fd3 | ||
|   | c1b734a3e1 | ||
|   | cf806748ec | ||
|   | b28dc011e0 | ||
|   | ee4fef3768 | ||
|   | 058a023fae | ||
|   | 0c367fef94 | ||
|   | a418d290f1 | ||
|   | 08cb30801c | ||
|   | 788de4f7ba | ||
|   | ebce0a16f6 | ||
|   | df546bd58c | ||
|   | 05221e9056 | ||
|   | e963714de6 | ||
|   | dc11239ff1 | ||
|   | d59841618d | ||
|   | 8d3964782a | ||
|   | 162c039e9d | ||
|   | 13648f8ccd | ||
|   | 5b809a3104 | ||
|   | 3daa54d636 | ||
|   | 8f1829d1d2 | ||
|   | 6efb6addf2 | ||
|   | d789097af0 | ||
|   | 4bd2d49ca1 | ||
|   | ecfede9b3c | ||
|   | cb04619de2 | ||
|   | 61e2e86aef | ||
|   | 9b86eecb94 | ||
|   | 35212da048 | ||
|   | 755e743cdd | ||
|   | 1a323390ec | ||
|   | 23559fd118 | ||
|   | d994a873a4 | ||
|   | b6575ce0b0 | ||
|   | e2b2a84497 | ||
|   | 86956c2261 | ||
|   | ef6dfdc7fd | ||
|   | f3b85ef79d | ||
|   | 1d7e42ee9f | ||
|   | 6dfb5b4e1f | ||
|   | 930085751c | ||
|   | 258c4686b2 | ||
|   | 600d0b1303 | ||
|   | 2f928797cf | ||
|   | f3f06e823c | ||
|   | 58292f49c5 | ||
|   | 5376d1047c | ||
|   | 1746b57161 | ||
|   | 0561bffab3 | ||
|   | 968e943eac | ||
|   | 5be00c95a7 | ||
|   | c80b9c3778 | ||
|   | 536f98a766 | ||
|   | c4e5613a7d | ||
|   | bff962398d | ||
|   | 2b15823dab | ||
|   | 59dcc7e191 | ||
|   | ea3fe98867 | ||
|   | 4f05613fbb | ||
|   | 22e52ddd6e | ||
|   | 1125d45397 | ||
|   | 44d408204a | ||
|   | 50feea3eef | ||
|   | ca95f58ac0 | ||
|   | ed636cbe44 | ||
|   | 738e4f410c | ||
|   | 4e731a0189 | ||
|   | 5cf6a539fe | ||
|   | 17fde12fb8 | ||
|   | 5c8b973d4f | ||
|   | b22e03b2b2 | ||
|   | a2926ebe7c | ||
|   | c508d70258 | ||
|   | f5971f54ff | ||
|   | c5b16d4468 | ||
|   | 3c71a1bab7 | ||
|   | 3ec322685b | ||
|   | 9a39839a43 | ||
|   | e87c996fe0 | ||
|   | 32195c673d | ||
|   | b99a61c5b0 | ||
|   | c960cd41e8 | ||
|   | a29471d0f7 | ||
|   | ba6f20a244 | ||
|   | 61572a1f97 | ||
|   | dee3844f13 | ||
|   | cbd1a77ec2 | ||
|   | 33f7ac06c3 | ||
|   | 70f10f1ac9 | ||
|   | 775b60fa09 | ||
|   | 66e4d391d3 | ||
|   | caf880be18 | ||
|   | c8355c27e9 | ||
|   | c2d7e2ae17 | ||
|   | 98ecad0da6 | ||
|   | bbc4e05434 | ||
|   | ad6e28073c | ||
|   | af29dcbafb | ||
|   | b9a7f4e502 | ||
|   | 51009a40b4 | ||
|   | 2ec8f77f21 | ||
|   | 7f62028d66 | ||
|   | d34fe06fb0 | ||
|   | 2f3d520571 | ||
|   | 48dd0c5673 | ||
|   | 8be493296d | ||
|   | 6f33531861 | ||
|   | 16897354bc | ||
|   | 823a0454a6 | ||
|   | 6790c559af | ||
|   | c56c4a0a47 | ||
|   | 45064c5778 | ||
|   | 7aba59f577 | ||
|   | 59b05ac383 | ||
|   | 9b15f1be26 | ||
|   | 38cd2d781f | ||
|   | 2f285b3f16 | ||
|   | 57d2fb41d0 | ||
|   | 0f77fe55b6 | ||
|   | 68ee002ad0 | ||
|   | 1fc3b18592 | ||
|   | 5a5287ef2a | ||
|   | 30c85c327b | ||
|   | ed3cc86390 | ||
|   | e5f1499f62 | ||
|   | 848f40fd65 | ||
|   | 5adf53dc01 | ||
|   | 15feb8217f | ||
|   | 59dccb34b0 | ||
|   | e8057241c6 | ||
|   | d3ee83747c | ||
|   | 3f55ed0ef7 | ||
|   | f9cfef3599 | ||
|   | 07dbfa25a0 | ||
|   | 1d49c04545 | ||
|   | faaaf62655 | ||
|   | 43885493ea | ||
|   | 1230422181 | ||
|   | 6a17cae4f6 | ||
|   | 1eac702c1a | ||
|   | 4b96ac504c | ||
|   | 0678a51d3b | ||
|   | b7dd186d36 | ||
|   | 26c1c8b2ad | ||
|   | 824aa5f918 | ||
|   | ca67dcbc05 | ||
|   | 9dbc2c827d | ||
|   | 91e27ce755 | ||
|   | 65ed696625 | ||
|   | 3e3eaaada7 | ||
|   | 8997d258f7 | ||
|   | a3f958aaaa | ||
|   | 38649d1362 | ||
|   | 4f00a02ba3 | ||
|   | edef367e9c | ||
|   | 08c5e2a194 | ||
|   | c67c54d4b3 | ||
|   | 23b05e8473 | ||
|   | 949ff9715a | ||
|   | b9a305983f | ||
|   | 8e7da9464a | ||
|   | e550df675a | ||
|   | f614fe4946 | ||
|   | e6ad066ed1 | ||
|   | 5b358603bd | ||
|   | 3910a61b61 | ||
|   | 45d9772667 | ||
|   | 268eebca01 | ||
|   | 1056dc9a26 | ||
|   | 053654dc4d | ||
|   | 7fe89c5d29 | ||
|   | 5c8fc7dce9 | ||
|   | e8d3710aff | ||
|   | d0fe681a28 | ||
|   | 9a70a6d0c0 | ||
|   | ee19b44fe0 | ||
|   | 8f0bef2fa0 | ||
|   | 33ddeb6dcc | ||
|   | e0dc7d6fc8 | ||
|   | 8f5909b664 | ||
|   | bef2e7f2ff | ||
|   | 8cfb0e26bb | ||
|   | 0164f0cf81 | ||
|   | 420ea83ef3 | ||
|   | 223e470e93 | ||
|   | e7387f7557 | ||
|   | 582bad89ef | ||
|   | 92433e596b | ||
|   | 5360f88393 | ||
|   | 949073d448 | ||
|   | 85877dae9a | ||
|   | c6ef31955a | ||
|   | 92aaff009d | ||
|   | 65ba6e3337 | ||
|   | fbb5518ab6 | ||
|   | a83b5d1b67 | ||
|   | add90abfa4 | ||
|   | a005243908 | ||
|   | 001a2d9b67 | ||
|   | 95446f694b | ||
|   | 4db954f802 | ||
|   | a171f60bf7 | ||
|   | 887e8f9265 | ||
|   | 07625fe243 | ||
|   | 61ffcd7815 | ||
|   | a9f47b9364 | ||
|   | 7831c1ae44 | ||
|   | 5ce3eb066e | ||
|   | 07b6e7363d | ||
|   | 2741f97a69 | ||
|   | d7fbe07ee2 | ||
|   | 2fce1f3e97 | ||
|   | d09bac137a | ||
|   | 43e8f00861 | ||
|   | 3337be81c8 | ||
|   | 0cc9122093 | ||
|   | 54bcde0a14 | ||
|   | 660c86ce95 | ||
|   | 50b3545ada | ||
|   | baac8065cf | ||
|   | 257e38d5c5 | ||
|   | fc70b2f916 | ||
|   | 33a8e6c30c | ||
|   | 3c875e0112 | ||
|   | 59136ece19 | ||
|   | 08fd1829e0 | ||
|   | 43a4604639 | ||
|   | 83f385acf3 | ||
|   | 606af3024b | ||
|   | 4449bd9b4d | ||
|   | bffa835573 | ||
|   | 6dd6b4d1fa | ||
|   | 67d94514b0 | ||
|   | 91b38857ef | ||
|   | 6d5f899761 | ||
|   | 77a3e3c7f7 | ||
|   | 81249965f7 | ||
|   | 45c6db9ac4 | ||
|   | 06be8bc389 | ||
|   | 0ac5fd354b | ||
|   | a11c8a6ea0 | ||
|   | 2858935187 | ||
|   | 43b10339ab | ||
|   | 3f3a38f9c6 | ||
|   | 4bf28cb904 | ||
|   | 1abde9009a | ||
|   | db85a941d0 | ||
|   | 1bfb0fc5da | ||
|   | ce1cfcb7a6 | ||
|   | ce81cd21d3 | ||
|   | 51c6a5d43b | ||
|   | 15b8da1980 | ||
|   | c1c257d19a | ||
|   | 08b9f73219 | ||
|   | 94162d62ac | ||
|   | 059707be32 | ||
|   | 048bfeaaef | ||
|   | a137109a0c | ||
|   | 17c01d21a9 | ||
|   | f5cad68d22 | ||
|   | 119364741e | ||
|   | 8d1239c091 | ||
|   | 30a39fe877 | ||
|   | 0489081d3f | ||
|   | 19c8da85d8 | ||
|   | b03abddb28 | ||
|   | ccf083e26d | ||
|   | dbd4abf0ff | ||
|   | 9ca2644429 | ||
|   | ec08e2f9f2 | ||
|   | 38dd0ede9d | ||
|   | 62c264bcdb | ||
|   | b108c664ac | ||
|   | 64db60397b | ||
|   | d243908a01 | ||
|   | c145fbea49 | ||
|   | 84fcff79f4 | ||
|   | f58ba5ab1c | ||
|   | 2694b970e8 | ||
|   | 23f5d145ec | ||
|   | b01ab65225 | ||
|   | 7a7f490efa | ||
|   | 95c15fce0c | ||
|   | c788efffd4 | ||
|   | c1a475e708 | ||
|   | d0de9663e2 | ||
|   | d6dd848523 | ||
|   | 9fc66e4dd9 | ||
|   | 6ecea9453b | ||
|   | 2c105af910 | ||
|   | bb667c8ac6 | ||
|   | 8179743cee | ||
|   | 3d59a3855a | ||
|   | 8388366849 | ||
|   | ef3b425b11 | ||
|   | 026d93b4f6 | ||
|   | 36710c4586 | ||
|   | 63ac6156aa | ||
|   | 08a70d117c | ||
|   | 6ce589c3ee | ||
|   | d426c20c0a | ||
|   | 54ca7d8cb2 | ||
|   | 0819c3a8cf | ||
|   | ad05b22de3 | ||
|   | 9fc8800b6d | ||
|   | a4d6611d26 | ||
|   | 015fc6aa17 | ||
|   | a739b9bc45 | ||
|   | 0bd2d54814 | ||
|   | 16b95fc773 | ||
|   | 9c5cd6c413 | ||
|   | 9b55056423 | ||
|   | fd4cf78f36 | ||
|   | a6315359d7 | ||
|   | 966130132f | ||
|   | a19de6e9ac | ||
|   | bdfeaa0f95 | ||
|   | c478200766 | ||
|   | 775f86cb5a | ||
|   | db1c92ceac | ||
|   | 0f4664d27f | ||
|   | 0f89a2e639 | ||
|   | 05b26e7566 | ||
|   | 6c511abf43 | ||
|   | bb6d0771c2 | ||
|   | 75f6c36e51 | ||
|   | 015d5869d7 | ||
|   | 4686adb433 | ||
|   | 785a4899f5 | ||
|   | da62aff6bb | ||
|   | 322308e298 | ||
|   | b53e326828 | ||
|   | 0885d787ab | ||
|   | 2620d78e94 | ||
|   | 8c3f40ee32 | ||
|   | b1aafbd957 | ||
|   | 45fd6685bd | ||
|   | 0159636373 | ||
|   | 7ac7c119be | ||
|   | 4f067b1d1c | ||
|   | ae60745e3e | ||
|   | 7f496d8c3f | ||
|   | 048c74f2fa | ||
|   | 0ed57d370d | ||
|   | 551abba277 | ||
|   | 9b11a84e74 | ||
|   | 26f8de459a | ||
|   | ceff98fd49 | ||
|   | e04151ed76 | ||
|   | cdb2552424 | ||
|   | b41e65a8e3 | ||
|   | be8c219ec2 | ||
|   | 099c011059 | ||
|   | 245a780711 | ||
|   | 05e4a3026d | ||
|   | 39a416f12a | ||
|   | 9b23b31071 | ||
|   | 8412d1e493 | ||
|   | 2ee41a5ffc | ||
|   | a18f599482 | ||
|   | 6d27647b61 | ||
|   | 3bc11344de | ||
|   | 3dbe708308 | ||
|   | 621709c623 | ||
|   | 9e241864e3 | ||
|   | cf613fdba4 | ||
|   | e6addcf624 | ||
|   | 9e88343a17 | ||
|   | 1ce732e9d6 | ||
|   | cc618e761c | ||
|   | 24db40de7c | ||
|   | 7350f9851a | ||
|   | d030dfa6e2 | ||
|   | 14d6db0873 | ||
|   | 0ff311aa1a | ||
|   | 8147c3659d | ||
|   | 73e91ce20c | ||
|   | 8780ff879c | ||
|   | 6fd1cfeab1 | ||
|   | 9d0533056c | ||
|   | 6c4f317f7f | ||
|   | 21ed69b51e | ||
|   | 3b819b3064 | ||
|   | 3fa60164af | ||
|   | ac6e0501c6 | ||
|   | 4f17c58315 | ||
|   | f6251734fc | ||
|   | 9f44a95522 | ||
|   | 4b60c3e9d3 | ||
|   | 5d4c981e13 | ||
|   | da4a776758 | ||
|   | 1b66c1da6c | ||
|   | 5cb2ee878c | ||
|   | 8cf0814a14 | ||
|   | 523767660c | ||
|   | 327c0d6b1c | ||
|   | 870842ccee | ||
|   | 68b215157f | ||
|   | a892cf2c12 | ||
|   | 7cba40b218 | ||
|   | d994fcf2b1 | ||
|   | 975fafdc49 | ||
|   | 9537580ba2 | ||
|   | bc0adcef1f | ||
|   | 7ffae92daf | ||
|   | abca03cf36 | ||
|   | 374f0214b6 | ||
|   | 4945b2454d | ||
|   | a5cb022407 | ||
|   | feb63efc31 | ||
|   | 4cf3ad07e5 | ||
|   | 557cc55f6f | ||
|   | 2d8dba388b | ||
|   | 91fd2c3bcd | ||
|   | d38891c950 | ||
|   | 381e372939 | ||
|   | c347db2e0a | ||
|   | 232a4553b8 | ||
|   | 014f1bea9a | ||
|   | 5b4f50857a | ||
|   | 6f10a718e4 | ||
|   | 658de40930 | ||
|   | 2c06e7f8ef | ||
|   | fa1c916943 | ||
|   | b132e865b9 | ||
|   | 77431568d2 | ||
|   | e16c1b8e28 | ||
|   | 1a8d8aa227 | ||
|   | d4c4fd6272 | ||
|   | acb905231d | ||
|   | c915eac93c | ||
|   | 72e675caee | ||
|   | e347cff0e4 | ||
|   | d79fdbc46e | ||
|   | ab13c2f814 | ||
|   | 138ca334f9 | ||
|   | 1aa82decea | ||
|   | 014fe6971e | ||
|   | 3217809294 | ||
|   | f3c7adcb54 | ||
|   | dcf698dc74 | ||
|   | 54117be639 | ||
|   | 5a79532aee | ||
|   | 29ac001aa6 | ||
|   | ccba0d10b6 | ||
|   | 7f7e42732d | ||
|   | ca410ec2ca | ||
|   | e5d8693865 | ||
|   | 46c92c0b80 | ||
|   | 7b5d148b1f | ||
|   | f4bc326670 | ||
|   | 327598e7b4 | ||
|   | 11caaad5f9 | ||
|   | 3e0845e182 | ||
|   | a2c7abea6c | ||
|   | 2f8f12e82e | ||
|   | 5cdcc2b3aa | ||
|   | 652e2cf57c | ||
|   | 8ee5e95ab1 | ||
|   | 22c61d8da6 | ||
|   | 1b88990cbb | ||
|   | df3e8e19c1 | ||
|   | 44dc36cc8f | ||
|   | 6d3701318d | ||
|   | d0edb47896 | ||
|   | b238e0b1b4 | ||
|   | 3f62bfb61d | ||
|   | c7a66d5af4 | ||
|   | 1866b95b7f | ||
|   | 668c204970 | ||
|   | af2d899d6b | ||
|   | d5ed9f787f | ||
|   | 259f27b09f | ||
|   | c1b9356081 | ||
|   | c669e1ae45 | ||
|   | 10203cada9 | ||
|   | 58b0415d36 | ||
|   | ad9cb40b6f | ||
|   | 2e60ca382d | ||
|   | 25920f4a14 | ||
|   | 160c302933 | ||
|   | dddc8e3374 | ||
|   | bccb1ee7cd | ||
|   | 26af759732 | ||
|   | 87fc4ad919 | ||
|   | b214298960 | ||
|   | 1926f4573d | ||
|   | 7fe65aaf5b | ||
|   | 0d3d84e3ff | ||
|   | e789a3802c | ||
|   | 4aabbc5ac2 | ||
|   | e7a50e37d6 | ||
|   | 9fa05db83b | ||
|   | 7ed58c4636 | ||
|   | f2f7c18245 | ||
|   | efaab37698 | ||
|   | 869319ce4a | ||
|   | 252f16db02 | ||
|   | 72f5d6ba46 | ||
|   | 5ec786b02e | ||
|   | 035ee257c8 | ||
|   | 188b08ca55 | ||
|   | 6f750f3b57 | ||
|   | 5a6dcdc36c | ||
|   | 59c16a570f | ||
|   | 50c10aa5bf | ||
|   | 006878686c | ||
|   | bd100b2a51 | ||
|   | 5b1bbffdff | ||
|   | 16710a1c9b | ||
|   | ba5c71b79b | ||
|   | f3799462c2 | ||
|   | f01c6e51f4 | ||
|   | 21d62118dc | ||
|   | de55038e33 | ||
|   | ea908c23ae | ||
|   | 844cbc701a | ||
|   | f1fa7b8ba4 | ||
|   | 86ff3194fa | ||
|   | d460b601f9 | ||
|   | 48a06d1a7b | ||
|   | 813a1107f4 | ||
|   | b3461bab1d | ||
|   | 5ecd56d964 | ||
|   | cc44fb1dc8 | ||
|   | 77b0efdbc2 | ||
|   | 68653bcbdd | ||
|   | 9af807a5ce | ||
|   | 4bbcc47f3f | ||
|   | 8ab495a088 | ||
|   | 84e7bb85b1 | ||
|   | 4fc7e13a98 | ||
|   | b465750041 | ||
|   | 37dc0fa519 | ||
|   | 000fdc6b99 | ||
|   | 594fc0411e | ||
|   | 94fcb4b09d | ||
|   | 1a0034ac34 | ||
|   | e3377e637a | ||
|   | 2ab854cafd | ||
|   | 4a2f0fb2be | ||
|   | dca3564cfb | ||
|   | 9d183bb7b1 | ||
|   | c7db74fe73 | ||
|   | 5251c45187 | ||
|   | d9b5f327bf | ||
|   | ca1356702a | ||
|   | 89d119646d | ||
|   | 989dd9c34a | ||
|   | 1d728aae2a | ||
|   | 98b9349be7 | ||
|   | 4706a93341 | ||
|   | b85b56a73d | ||
|   | 1da3d402f6 | ||
|   | 1da3192d2d | ||
|   | dab569d76c | ||
|   | 598c589359 | ||
|   | 15c8219340 | ||
|   | 5ae21ebde9 | ||
|   | c7e0d8c30b | ||
|   | fee4f8c86d | ||
|   | 1261c3feba | ||
|   | 7fc300d5dc | ||
|   | 88ce03e945 | ||
|   | 5bed99c97d | ||
|   | 46c699c483 | ||
|   | f7d6e147f1 | ||
|   | aad1d3ce14 | ||
|   | cf5378b366 | ||
|   | fea938cbcb | ||
|   | a67c8b4698 | ||
|   | 49ce3e5160 | ||
|   | 4a728747e6 | ||
|   | f5a6355172 | ||
|   | ffff8ddbef | ||
|   | cf86f8cb78 | ||
|   | a53ba060c8 | ||
|   | 72bb5854f7 | ||
|   | 0de56e5535 | ||
|   | 0878b14f79 | ||
|   | 7d56f35388 | ||
|   | d12759c73e | ||
|   | c0095d6dd9 | ||
|   | 6a88eab067 | ||
|   | a4f36558fc | ||
|   | 5e1cd407a3 | ||
|   | 2a1345ae9f | ||
|   | cf61c8d659 | ||
|   | c39690486c | ||
|   | 814b471d55 | ||
|   | 5119fb16d6 | ||
|   | dc2c70be07 | ||
|   | 19631f5d5f | ||
|   | a8d6b40736 | ||
|   | 8026d94c07 | ||
|   | 93bd512357 | ||
|   | 04d3a8c714 | 
| @@ -4,6 +4,7 @@ Makefile | |||||||
| libtool | libtool | ||||||
| Makefile.in | Makefile.in | ||||||
| aclocal.m4 | aclocal.m4 | ||||||
|  | aclocal.m4.bak | ||||||
| configure | configure | ||||||
| config.h | config.h | ||||||
| config.status | config.status | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								COPYING
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								COPYING
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| COPYRIGHT AND PERMISSION NOTICE | COPYRIGHT AND PERMISSION NOTICE | ||||||
|  |  | ||||||
| Copyright (c) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>. | Copyright (c) 1996 - 2008, Daniel Stenberg, <daniel@haxx.se>. | ||||||
|  |  | ||||||
| All rights reserved. | All rights reserved. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								CVS-INFO
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								CVS-INFO
									
									
									
									
									
								
							| @@ -12,8 +12,8 @@ inner sanctum. | |||||||
|  |  | ||||||
| Compile and build instructions follow below. | Compile and build instructions follow below. | ||||||
|  |  | ||||||
|   CHANGES.0     contains ancient changes. |   CHANGES.0     contains ancient changes | ||||||
|   CHANGES.$year contains changes for the particular year. |   CHANGES       contains the most recent changes | ||||||
|  |  | ||||||
|   Makefile.dist is included as the root Makefile in distribution archives |   Makefile.dist is included as the root Makefile in distribution archives | ||||||
|  |  | ||||||
| @@ -49,9 +49,8 @@ installed: | |||||||
|  |  | ||||||
|    If you don't have nroff and perl and you for some reason don't want to |    If you don't have nroff and perl and you for some reason don't want to | ||||||
|    install them, you can rename the source file src/hugehelp.c.cvs to |    install them, you can rename the source file src/hugehelp.c.cvs to | ||||||
|    src/hugehelp.c and avoid having to generate this file. This will of course |    src/hugehelp.c and avoid having to generate this file. This will give you | ||||||
|    give you an older version of the file that isn't up-to-date. That file was |    a stubbed version of the file that doesn't contain actual content. | ||||||
|    checked in once and won't be updated very regularly. |  | ||||||
|  |  | ||||||
| MAC OS X | MAC OS X | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								Makefile.am
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
| #                            | (__| |_| |  _ <| |___ | #                            | (__| |_| |  _ <| |___ | ||||||
| #                             \___|\___/|_| \_\_____| | #                             \___|\___/|_| \_\_____| | ||||||
| # | # | ||||||
| # Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. | # Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
| # | # | ||||||
| # This software is licensed as described in the file COPYING, which | # This software is licensed as described in the file COPYING, which | ||||||
| # you should have received as part of this distribution. The terms | # you should have received as part of this distribution. The terms | ||||||
| @@ -23,8 +23,11 @@ | |||||||
|  |  | ||||||
| AUTOMAKE_OPTIONS = foreign | AUTOMAKE_OPTIONS = foreign | ||||||
|  |  | ||||||
|  | ACLOCAL_AMFLAGS = -I m4 | ||||||
|  |  | ||||||
| EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist curl-config.in \ | EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist curl-config.in \ | ||||||
|  curl-style.el sample.emacs RELEASE-NOTES buildconf buildconf.bat libcurl.pc.in |  curl-style.el sample.emacs RELEASE-NOTES buildconf buildconf.bat 	 \ | ||||||
|  |  libcurl.pc.in vc6curl.dsw | ||||||
|  |  | ||||||
| bin_SCRIPTS = curl-config | bin_SCRIPTS = curl-config | ||||||
|  |  | ||||||
| @@ -49,7 +52,7 @@ html: | |||||||
| pdf: | pdf: | ||||||
| 	cd docs; make pdf | 	cd docs; make pdf | ||||||
|  |  | ||||||
| check: test | check: test examples | ||||||
|  |  | ||||||
| if CROSSCOMPILING | if CROSSCOMPILING | ||||||
| test-full: test | test-full: test | ||||||
| @@ -71,6 +74,9 @@ test-torture: | |||||||
|  |  | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | examples: | ||||||
|  | 	@(cd docs/examples; $(MAKE) check) | ||||||
|  |  | ||||||
| # | # | ||||||
| # Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros | # Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros | ||||||
| # must contain the following line: | # must contain the following line: | ||||||
| @@ -128,3 +134,11 @@ install-data-hook: | |||||||
| uninstall-hook: | uninstall-hook: | ||||||
| 	cd include && $(MAKE) uninstall | 	cd include && $(MAKE) uninstall | ||||||
| 	cd docs && $(MAKE) uninstall | 	cd docs && $(MAKE) uninstall | ||||||
|  |  | ||||||
|  | ca-bundle: lib/mk-ca-bundle.pl | ||||||
|  | 	@echo "generate a fresh ca-bundle.crt" | ||||||
|  | 	@perl $< -b -l -u lib/ca-bundle.crt | ||||||
|  |  | ||||||
|  | ca-firefox: lib/firefox-db2pem.sh | ||||||
|  | 	@echo "generate a fresh ca-bundle.crt" | ||||||
|  | 	./lib/firefox-db2pem.sh lib/ca-bundle.crt | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| #                            | (__| |_| |  _ <| |___ | #                            | (__| |_| |  _ <| |___ | ||||||
| #                             \___|\___/|_| \_\_____| | #                             \___|\___/|_| \_\_____| | ||||||
| # | # | ||||||
| # Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. | # Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
| # | # | ||||||
| # This software is licensed as described in the file COPYING, which | # This software is licensed as described in the file COPYING, which | ||||||
| # you should have received as part of this distribution. The terms | # you should have received as part of this distribution. The terms | ||||||
| @@ -68,18 +68,22 @@ watcom-clean: | |||||||
| 	wmake -f Makefile.Watcom clean | 	wmake -f Makefile.Watcom clean | ||||||
|  |  | ||||||
| mingw32: | mingw32: | ||||||
|  | 	$(MAKE) -C lib -f Makefile.m32 | ||||||
|  | 	$(MAKE) -C src -f Makefile.m32 | ||||||
|  |  | ||||||
|  | mingw32-zlib: | ||||||
| 	$(MAKE) -C lib -f Makefile.m32 ZLIB=1 | 	$(MAKE) -C lib -f Makefile.m32 ZLIB=1 | ||||||
| 	$(MAKE) -C src -f Makefile.m32 ZLIB=1 | 	$(MAKE) -C src -f Makefile.m32 ZLIB=1 | ||||||
|  |  | ||||||
| mingw32-ssl: | mingw32-ssl-zlib: | ||||||
| 	$(MAKE) -C lib -f Makefile.m32 SSL=1 ZLIB=1 | 	$(MAKE) -C lib -f Makefile.m32 SSL=1 ZLIB=1 | ||||||
| 	$(MAKE) -C src -f Makefile.m32 SSL=1 ZLIB=1 | 	$(MAKE) -C src -f Makefile.m32 SSL=1 ZLIB=1 | ||||||
|  |  | ||||||
| mingw32-ssh2-ssl: | mingw32-ssh2-ssl-zlib: | ||||||
| 	$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1 | 	$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1 | ||||||
| 	$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1 | 	$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 ZLIB=1 | ||||||
|  |  | ||||||
| mingw32-ssh2-ssl-sspi: | mingw32-ssh2-ssl-sspi-zlib: | ||||||
| 	$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1 | 	$(MAKE) -C lib -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1 | ||||||
| 	$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1 | 	$(MAKE) -C src -f Makefile.m32 SSH2=1 SSL=1 SSPI=1 ZLIB=1 | ||||||
|  |  | ||||||
| @@ -124,6 +128,12 @@ vc: | |||||||
| 	cd ..\src | 	cd ..\src | ||||||
| 	nmake /f Makefile.$(VC) | 	nmake /f Makefile.$(VC) | ||||||
|  |  | ||||||
|  | vc-x64: | ||||||
|  | 	cd lib | ||||||
|  | 	MACHINE=x64 nmake /f Makefile.$(VC) cfg=release | ||||||
|  | 	cd ..\src | ||||||
|  | 	MACHINE=x64 nmake /f Makefile.$(VC) | ||||||
|  |  | ||||||
| vc-zlib: | vc-zlib: | ||||||
| 	cd lib | 	cd lib | ||||||
| 	nmake /f Makefile.$(VC) cfg=release-zlib | 	nmake /f Makefile.$(VC) cfg=release-zlib | ||||||
| @@ -247,6 +257,14 @@ linux: all | |||||||
| linux-ssl: ssl | linux-ssl: ssl | ||||||
|  |  | ||||||
| vc8: | vc8: | ||||||
| 	echo "generate VC8 makefiles" | 	@echo "generate VC8 makefiles" | ||||||
| 	sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e 's#/GZ#/RTC1#' -e 's/wsock32.lib/wsock32.lib bufferoverflowu.lib/g' -e 's/VC6/VC8/g' lib/Makefile.vc6 > lib/Makefile.vc8 | 	@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" lib/Makefile.vc6 > lib/Makefile.vc8 | ||||||
| 	sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e 's#/GZ#/RTC1#' -e 's/wsock32.lib/wsock32.lib bufferoverflowu.lib/g' -e 's/VC6/VC8/g' src/Makefile.vc6 > src/Makefile.vc8 | 	@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" src/Makefile.vc6 > src/Makefile.vc8 | ||||||
|  |  | ||||||
|  | ca-bundle: lib/mk-ca-bundle.pl | ||||||
|  | 	@echo "generate a fresh ca-bundle.crt" | ||||||
|  | 	@perl $< -b -l -u lib/ca-bundle.crt | ||||||
|  |  | ||||||
|  | ca-firefox: lib/firefox-db2pem.sh | ||||||
|  | 	@echo "generate a fresh ca-bundle.crt" | ||||||
|  | 	./lib/firefox-db2pem.sh lib/ca-bundle.crt | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								README
									
									
									
									
									
								
							| @@ -30,10 +30,9 @@ CONTACT | |||||||
|  |  | ||||||
| WEB SITE | WEB SITE | ||||||
|  |  | ||||||
|   Visit the curl web site or mirrors for the latest news and downloads: |   Visit the curl web site for the latest news and downloads: | ||||||
|  |  | ||||||
|         Sweden       http://curl.haxx.se/ |         http://curl.haxx.se/ | ||||||
|         Mirrors      http://curlm.haxx.se/ |  | ||||||
|  |  | ||||||
| CVS | CVS | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,30 +1,69 @@ | |||||||
| Curl and libcurl 7.16.4 | Curl and libcurl 7.19.0 | ||||||
|  |  | ||||||
|  Public curl release number:               100 |  Public curl releases:         106 | ||||||
|  Releases counted from the very beginning: 126 |  Command line options:         127 | ||||||
|  Available command line options:           118 |  curl_easy_setopt() options:   153 | ||||||
|  Available curl_easy_setopt() options:     143 |  Public functions in libcurl:  58 | ||||||
|  Number of public functions in libcurl:    55 |  Known libcurl bindings:       36 | ||||||
|  Amount of public web site mirrors:        39 |  Contributors:                 654 | ||||||
|  Number of known libcurl bindings:         35 |  | ||||||
|  Number of contributors:                   572 |  | ||||||
|  |  | ||||||
| This release includes the following changes: | This release includes the following changes: | ||||||
|  |  | ||||||
|  o added CURLOPT_NEW_FILE_PERMS and CURLOPT_NEW_DIRECTORY_PERMS |  o curl_off_t gets its size/typedef somewhat differently than before. This _may_ | ||||||
|  o improved hashing of sockets for the multi_socket API |    cause an ABI change for you. See lib/README.curl_off_t for a full explanation. | ||||||
|  o ftp kerberos5 support added |   | ||||||
|  |  o Added CURLINFO_PRIMARY_IP | ||||||
|  |  o Added CURLOPT_CRLFILE and CURLE_SSL_CRL_BADFILE | ||||||
|  |  o Added CURLOPT_ISSUERCERT and CURLE_SSL_ISSUER_ERROR | ||||||
|  |  o curl's option parser for boolean options reworked | ||||||
|  |  o Added --remote-name-all | ||||||
|  |  o Now builds for the INTEGRITY operating system | ||||||
|  |  o Added CURLINFO_APPCONNECT_TIME | ||||||
|  |  o Added test selection by key word in runtests.pl | ||||||
|  |  o the curl tool's -w option support the %{ssl_verify_result} variable | ||||||
|  |  o Added CURLOPT_ADDRESS_SCOPE and scope parsing of the URL according to RFC4007 | ||||||
|  |  o Support --append on SFTP uploads (not with OpenSSH, though) | ||||||
|  |  o Added curlbuild.h and curlrules.h to the external library interface | ||||||
|  |  | ||||||
| This release includes the following bugfixes: | This release includes the following bugfixes: | ||||||
|  |  | ||||||
|  o adjusted how libcurl treats HTTP 1.1 responses without content-lenth or |  o Fixed curl-config --ca | ||||||
|    chunked encoding |  o Fixed the multi interface connection re-use with NSS-built libcurl | ||||||
|  o fixed the 10-at-a-time.c example |  o connection re-use when using the multi interface with pipelining enabled | ||||||
|  o FTP over SOCKS proxy |  o curl_multi_socket() socket callback fix for close/re-create sockets case | ||||||
|  o improved error messages on SCP upload failures |  o SCP or SFTP over socks proxy crashed | ||||||
|  o security flaw (http://curl.haxx.se/docs/adv_20070710.html) in which libcurl |  o RC4-MD5 cipher now works with NSS-built libcurl | ||||||
|    failed to properly reject some outdated or not yet valid server certificates |  o range requests with --head are now done correctly | ||||||
|    when built with GnuTLS |  o fallback to gettimeofday when monotonic clock is unavailable at run-time | ||||||
|  |  o range numbers could be made to wrongly get output as signed | ||||||
|  |  o unexpected 1xx responses hung transfers | ||||||
|  |  o FTP transfers segfault when using different CURLOPT_FTP_FILEMETHOD | ||||||
|  |  o c-ares powered libcurls can resolve/use IPv6 addresses | ||||||
|  |  o poll not working on Windows Vista due to POLLPRI being incorrectly used | ||||||
|  |  o user-agent in CONNECT with non-HTTP protocols | ||||||
|  |  o CURL_READFUNC_PAUSE problems fixed | ||||||
|  |  o --use-ascii now works on Symbian OS, MS-DOS and OS/2 | ||||||
|  |  o CURLINFO_SSL_VERIFYRESULT is fixed | ||||||
|  |  o FTP URLs and IPv6 URLs mangled when sent to proxy with CURLOPT_PORT set | ||||||
|  |  o a user name in a proxy URL without a password was parsed incorrectly | ||||||
|  |  o library will now be built with _REENTRANT symbol defined only if needed | ||||||
|  |  o no longer link with gdi32 on Windows cross-compiled targets | ||||||
|  |  o HTTP PUT with -C - sent bad Content-Range: header | ||||||
|  |  o HTTP PUT or POST with redirect could lead to hang | ||||||
|  |  o re-use of connections with failed SSL connects in the multi interface | ||||||
|  |  o NTLM over proxy state was wrongly cleared when host connection was closed | ||||||
|  |  o Windows SSPI DLL loading is now done in curl_global_init() | ||||||
|  |  o runtests.pl has an improved find-stunnel-and-invoke | ||||||
|  |  o FTP sessions could go out of sync on a long header boundary condition | ||||||
|  |  o potential buffer overflows in the MS-DOS command-line port fixed | ||||||
|  |  o --stderr is now honoured with the -v option | ||||||
|  |  o memory leak in libcurl on Windows built with OpenSSL | ||||||
|  |  o improved curl_m*printf() integral data type size and signedness handling | ||||||
|  |  o error when --dump-header - used with more than one URL | ||||||
|  |  o proxy closing connect during CONNECT with auth with the multi interface | ||||||
|  |  o CURLOPT_UPLOAD sets HTTP method back to GET or HEAD when passed in a 0 | ||||||
|  |  o shared cookies could get locked twice | ||||||
|  |  o deal with closed connection while doing POST/PUT | ||||||
|  |  | ||||||
| This release includes the following known bugs: | This release includes the following known bugs: | ||||||
|  |  | ||||||
| @@ -34,14 +73,16 @@ Other curl-related news: | |||||||
|  |  | ||||||
|  o  |  o  | ||||||
|  |  | ||||||
| New curl mirrors: |  | ||||||
|  |  | ||||||
|  o  |  | ||||||
|  |  | ||||||
| This release would not have looked like this without help, code, reports and | This release would not have looked like this without help, code, reports and | ||||||
| advice from friends like these: | advice from friends like these: | ||||||
|  |  | ||||||
|  Robert Iakobashvili, James Housley, G<>nter Knauf, James Bursa, Song Ma, |  Lenny Rachitsky, Axel Tillequin, Arnaud Ebalard, Yang Tse, Dan Fandrich, | ||||||
|  Thomas J. Moore, Gavrie Philipson, Kees Cook |  Rob Crittenden, Dengminwen, Christopher Palow, Hans-Jurgen May, | ||||||
|  |  Phil Pellouchoud, Eduard Bloch, John Lightsey, Stephen Collyer, Tor Arntsen, | ||||||
|  |  Rolland Dudemaine, Phil Blundell, Scott Barrett, Andreas Schuldei, | ||||||
|  |  Peter Lamberg, David Bau, Pramod Sharma, Yehoshua Hershberg, | ||||||
|  |  Constantine Sapuntzakis, Lars Nilsson, Andy Tsouladze, Jamie Lokier, | ||||||
|  |  Vincent Le Normand | ||||||
|  |  | ||||||
|  |  | ||||||
|         Thanks! (and sorry if I forgot to mention someone) |         Thanks! (and sorry if I forgot to mention someone) | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								TODO-RELEASE
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								TODO-RELEASE
									
									
									
									
									
								
							| @@ -1,5 +1,26 @@ | |||||||
| To be addressed before 7.16.3 (planned release: June 2007) | To be addressed before 7.19.0 (planned release: August 2008) | ||||||
| ============================= | ============================= | ||||||
|  |  | ||||||
| 93 -  |  | ||||||
|  |  | ||||||
|  | To be addressed before 7.19.1 (planned release: October 2008) | ||||||
|  | ============================= | ||||||
|  |  | ||||||
|  | 157 - the CERTINFO patch as posted to: | ||||||
|  |       http://curl.haxx.se/mail/lib-2008-08/0105.html | ||||||
|  |  | ||||||
|  | 158 - Martin Drasar's CURLOPT_POSTREDIR work: | ||||||
|  |       http://curl.haxx.se/mail/lib-2008-08/0170.html | ||||||
|  |  | ||||||
|  | 162 - Craig Perras' note "http upload: how to stop on error" | ||||||
|  |       http://curl.haxx.se/mail/archive-2008-08/0138.html | ||||||
|  |  | ||||||
|  | 163 - Detecting illegal attempts at chunked transfers on HTTP 1.0 | ||||||
|  |       (tests 1069, 1072, 1073) | ||||||
|  |       http://curl.haxx.se/mail/archive-2008-08/0435.html | ||||||
|  |  | ||||||
|  | 164 - Automatic downgrading to HTTP 1.0 (tests 1071 through 1074) | ||||||
|  |  | ||||||
|  | 165 - "Problem with CURLOPT_RESUME_FROM and CURLOPT_APPEND" by Daniele Pinau, | ||||||
|  |       recipe: http://curl.haxx.se/mail/lib-2008-08/0439.html | ||||||
|  |  | ||||||
|  | 166 - | ||||||
|   | |||||||
							
								
								
									
										2809
									
								
								acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										2809
									
								
								acinclude.m4
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -21,3 +21,4 @@ depcomp | |||||||
| libcares.la | libcares.la | ||||||
| missing | missing | ||||||
| ares_version.h.dist | ares_version.h.dist | ||||||
|  | libcares.pc | ||||||
|   | |||||||
							
								
								
									
										47
									
								
								ares/AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								ares/AUTHORS
									
									
									
									
									
								
							| @@ -1,28 +1,37 @@ | |||||||
| c-ares is based on ares, and these are the people that have worked on it since | c-ares is based on ares, and these are the people that have worked on it since | ||||||
| the fork was made: | the fork was made: | ||||||
|  |  | ||||||
| Daniel Stenberg | Alexander Lazic | ||||||
| Dominick Meglio | Alexey Simak | ||||||
| liren at vivisimo.com | Andreas Rieke | ||||||
| James Bursa | Ashish Sharma | ||||||
| Duncan Wilcox | Brad House | ||||||
| Dirk Manske | Brad Spencer | ||||||
|  | Bram Matthys | ||||||
| Dan Fandrich | Dan Fandrich | ||||||
|  | Daniel Stenberg | ||||||
|  | Dirk Manske | ||||||
|  | Dominick Meglio | ||||||
|  | Doug Goldstein | ||||||
|  | Duncan Wilcox | ||||||
|  | Eino Tuominen | ||||||
|  | Erik Kline | ||||||
|  | George Neill | ||||||
| Gisle Vanem | Gisle Vanem | ||||||
|  | Guilherme Balena Versiani | ||||||
| Gunter Knauf | Gunter Knauf | ||||||
| Henrik Stoerner | Henrik Stoerner | ||||||
| Yang Tse | James Bursa | ||||||
| Nick Mathewson |  | ||||||
| Alexander Lazic |  | ||||||
| Andreas Rieke |  | ||||||
| Guilherme Balena Versiani |  | ||||||
| Brad Spencer |  | ||||||
| Ravi Pratap |  | ||||||
| William Ahern |  | ||||||
| Bram Matthys |  | ||||||
| Michael Wallner | Michael Wallner | ||||||
| Vlad Dinulescu | Nick Mathewson | ||||||
| Brad House | Phil Blundell | ||||||
|  | Ravi Pratap | ||||||
|  | Robin Cornelius | ||||||
|  | Sebastian at basti79.de | ||||||
| Shmulik Regev | Shmulik Regev | ||||||
| Ashish Sharma | Steinar H. Gunderson | ||||||
| Brad Spencer | Tofu Linden | ||||||
|  | Vlad Dinulescu | ||||||
|  | William Ahern | ||||||
|  | Yang Tse | ||||||
|  | liren at vivisimo.com | ||||||
|   | |||||||
							
								
								
									
										257
									
								
								ares/CHANGES
									
									
									
									
									
								
							
							
						
						
									
										257
									
								
								ares/CHANGES
									
									
									
									
									
								
							| @@ -1,5 +1,262 @@ | |||||||
|   Changelog for the c-ares project |   Changelog for the c-ares project | ||||||
|  |  | ||||||
|  | Version 1.5.3 (Aug 29, 2008) | ||||||
|  |  | ||||||
|  | * Aug 25 2008 (Yang Tse) | ||||||
|  | - Improvement by Brad House: | ||||||
|  |  | ||||||
|  |   This patch addresses an issue in which a response could be sent back to the | ||||||
|  |   source port of a client from a different address than the request was made to. | ||||||
|  |   This is one form of a DNS cache poisoning attack. | ||||||
|  |  | ||||||
|  |   The patch simply uses recvfrom() rather than recv() and validates that the | ||||||
|  |   address returned from recvfrom() matches the address of the server we have | ||||||
|  |   connected to. Only necessary on UDP sockets as they are connection-less, TCP | ||||||
|  |   is unaffected. | ||||||
|  |  | ||||||
|  | - Fix by George Neill: | ||||||
|  |   Fixed compilation of acountry sample application failure on some systems. | ||||||
|  |  | ||||||
|  | * Aug 4 2008 (Daniel Stenberg) | ||||||
|  | - Fix by Tofu Linden: | ||||||
|  |  | ||||||
|  |   The symptom: | ||||||
|  |   * Users (usually, but not always) on 2-Wire routers and the Comcast service | ||||||
|  |   and a wired connection to their router would find that the second and | ||||||
|  |   subsequent DNS lookups from fresh processes using c-ares to resolve the same | ||||||
|  |   address would cause the process to never see a reply (it keeps polling for | ||||||
|  |   around 1m15s before giving up). | ||||||
|  |  | ||||||
|  |   The repro: | ||||||
|  |   * On such a machine (and yeah, it took us a lot of QA to find the systems | ||||||
|  |   that reproduce such a specific problem!), do 'ahost www.secondlife.com', | ||||||
|  |   then do it again.  The first process's lookup will work, subsequent lookups | ||||||
|  |   will time-out and fail. | ||||||
|  |  | ||||||
|  |   The cause: | ||||||
|  |   * init_id_key() was calling randomize_key() *before* it initialized | ||||||
|  |   key->state, meaning that the randomness generated by randomize_key() is | ||||||
|  |   immediately overwritten with deterministic values. (/dev/urandom was also | ||||||
|  |   being read incorrectly in the c-ares version we were using, but this was | ||||||
|  |   fixed in a later version.) | ||||||
|  |   * This makes the stream of generated query-IDs from any new c-ares process | ||||||
|  |   be an identical and predictable sequence of IDs. | ||||||
|  |   * This makes the 2-Wire's default built-in DNS server detect these queries | ||||||
|  |   as probable-duplicates and (erroneously) not respond at all. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | * Aug 4 2008 (Yang Tse) | ||||||
|  | - Autoconf 2.62 has changed the behaviour of the AC_AIX macro which we use. | ||||||
|  |   Prior versions of autoconf defined _ALL_SOURCE if _AIX was defined. 2.62 | ||||||
|  |   version of AC_AIX defines _ALL_SOURCE and other four preprocessor symbols | ||||||
|  |   no matter if the system is AIX or not. To keep the traditional behaviour, | ||||||
|  |   and an uniform one across autoconf versions AC_AIX is replaced with our | ||||||
|  |   own internal macro CARES_CHECK_AIX_ALL_SOURCE. | ||||||
|  |  | ||||||
|  | * Aug 1 2008 (Yang Tse) | ||||||
|  | - Configure process now checks if the preprocessor _REENTRANT symbol is already | ||||||
|  |   defined. If it isn't currently defined a set of checks are performed to test | ||||||
|  |   if its definition is required to make visible to the compiler a set of *_r | ||||||
|  |   functions. Finally, if _REENTRANT is already defined or needed it takes care | ||||||
|  |   of making adjustments necessary to ensure that it is defined equally for the | ||||||
|  |   configure process tests and generated config file. | ||||||
|  |  | ||||||
|  | * Jul 20 2008 (Yang Tse) | ||||||
|  | - When recvfrom prototype uses a void pointer for arguments 2, 5 or 6 this will | ||||||
|  |   now cause the definition, as appropriate, of RECVFROM_TYPE_ARG2_IS_VOID, | ||||||
|  |   RECVFROM_TYPE_ARG5_IS_VOID or RECVFROM_TYPE_ARG6_IS_VOID. | ||||||
|  |  | ||||||
|  | * Jul 17 2008 (Yang Tse) | ||||||
|  | - RECVFROM_TYPE_ARG2, RECVFROM_TYPE_ARG5 and RECVFROM_TYPE_ARG6 are now defined | ||||||
|  |   to the data type pointed by its respective argument and not the pointer type. | ||||||
|  |  | ||||||
|  | * Jul 16 2008 (Yang Tse) | ||||||
|  | - Improved configure detection of number of arguments for getservbyport_r. | ||||||
|  |   Detection is now based on compilation checks instead of linker ones. | ||||||
|  |  | ||||||
|  | - Configure process now checks availability of recvfrom() socket function and | ||||||
|  |   finds out its return type and the types of its arguments. Added definitions | ||||||
|  |   for non-configure systems config files, and introduced macro sreadfrom which | ||||||
|  |   will be used on udp sockets as a recvfrom() wrapper in the future. | ||||||
|  |  | ||||||
|  | * Jul 15 2008 (Yang Tse) | ||||||
|  | - Introduce definition of _REENTRANT symbol in setup.h to improve library | ||||||
|  |   usability.  Previously the configure process only used the AC_SYS_LARGEFILE | ||||||
|  |   macro for debug builds, now it is also used for non-debug ones enabling the | ||||||
|  |   use of configure options --enable-largefile and --disable-largefile which | ||||||
|  |   might be needed for library compatibility.  Remove checking the size of | ||||||
|  |   curl_off_t, it is no longer needed. | ||||||
|  |  | ||||||
|  | * Jul 3 2008 (Daniel Stenberg) | ||||||
|  | - Phil Blundell: If you ask ares_gethostbyname() to do an AF_INET6 lookup and | ||||||
|  |   the target host has only A records, it automatically falls back to an | ||||||
|  |   AF_INET lookup and gives you the A results.  However, if the target host has | ||||||
|  |   a CNAME record, this behaviour is defeated since the original query does | ||||||
|  |   return some data even though ares_parse_aaa_reply() doesn't consider it | ||||||
|  |   relevant. Here's a small patch to make it behave the same with and without | ||||||
|  |   the CNAME. | ||||||
|  |  | ||||||
|  | * Jul 2 2008 (Yang Tse) | ||||||
|  | - Fallback to gettimeofday when monotonic clock is unavailable at run-time. | ||||||
|  |  | ||||||
|  | * Jun 30 2008 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - As was pointed out to me by Andreas Schuldei, the MAXHOSTNAMELEN define is | ||||||
|  |   not posix or anything and thus c-ares failed to build on hurd (and possibly | ||||||
|  |   elsewhere). The define was also somewhat artificially used in the windows | ||||||
|  |   port. Now, I instead rewrote the use of gethostbyname to enlarge the host | ||||||
|  |   name buffer in case of need and totally avoid the use of the MAXHOSTNAMELEN | ||||||
|  |   define. I thus also removed the defien from the namser.h file where it was | ||||||
|  |   once added for the windows build. | ||||||
|  |  | ||||||
|  |   I also fixed init_by_defaults() function to not leak memory in case if | ||||||
|  |   error. | ||||||
|  |  | ||||||
|  | * Jun 9 2008 (Yang Tse) | ||||||
|  |  | ||||||
|  | - Make libcares.pc generated file for pkg-config include information relative | ||||||
|  |   to the libraries needed for the static linking of c-ares. | ||||||
|  |  | ||||||
|  | * May 30 2008 (Yang Tse) | ||||||
|  |  | ||||||
|  | - Brad House fixed a missing header file inclusion in adig sample program. | ||||||
|  |  | ||||||
|  | Version 1.5.2 (May 29, 2008) | ||||||
|  |  | ||||||
|  | * May 13 2008 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Introducing millisecond resolution support for the timeout option. See | ||||||
|  |   ares_init_options()'s ARES_OPT_TIMEOUTMS. | ||||||
|  |  | ||||||
|  | * May 9 2008 (Yang Tse) | ||||||
|  |  | ||||||
|  | - Use monotonic time source if available, for private function ares__tvnow() | ||||||
|  |  | ||||||
|  | * May 7 2008 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Sebastian made c-ares able to return all PTR-records when doing reverse | ||||||
|  |   lookups. It is not common practice to have multiple PTR-Records for a single | ||||||
|  |   IP, but its perfectly legal and some sites have those. | ||||||
|  |  | ||||||
|  | - Doug Goldstein provided a configure patch: updates autoconf 2.13 usage to | ||||||
|  |   autoconf 2.57 usage (which is the version you have specified as the minimum | ||||||
|  |   version). It's a minor change but it does clean up some warnings with newer | ||||||
|  |   autoconf (specifically 2.62). | ||||||
|  |  | ||||||
|  | * May 5 2008 (Yang Tse) | ||||||
|  |  | ||||||
|  | - Improved parsing of resolver configuration files. | ||||||
|  |  | ||||||
|  | * April 4 2008 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Eino Tuominen improved the code when a file is used to seed the randomizer. | ||||||
|  |  | ||||||
|  | - Alexey Simak made adig support NAPTR records | ||||||
|  |  | ||||||
|  | - Alexey Simak fixed the VC dsp file by adding the missing source file | ||||||
|  |   ares_expand_string.c | ||||||
|  |  | ||||||
|  | * December 11 2007 (Gisle Vanem) | ||||||
|  |  | ||||||
|  | - Added another sample application; acountry.c which converts an | ||||||
|  |   IPv4-address(es) and/or host-name(s) to country-name and country-code. | ||||||
|  |   This uses the service of the DNSBL at countries.nerd.dk. | ||||||
|  |  | ||||||
|  | * December 3 2007 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Brad Spencer fixed the configure script to assume that there's no | ||||||
|  |   /dev/urandom when built cross-compiled as then the script cannot check for | ||||||
|  |   it. | ||||||
|  |  | ||||||
|  | - Erik Kline cleaned up ares_gethostbyaddr.c:next_lookup() somewhat | ||||||
|  |  | ||||||
|  | Version 1.5.1 (Nov 21, 2007) | ||||||
|  |  | ||||||
|  | * November 21 2007 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Robin Cornelius pointed out that ares_llist.h was missing in the release | ||||||
|  |   archive for 1.5.0 | ||||||
|  |  | ||||||
|  | Version 1.5.0 (Nov 21, 2007) | ||||||
|  |  | ||||||
|  | * October 2 2007 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - ares_strerror() segfaulted if the input error number was out of the currently | ||||||
|  |   supported range. | ||||||
|  |  | ||||||
|  | - Yang Tse: Avoid a segfault when generating a DNS "Transaction ID" in | ||||||
|  |   internal function init_id_key() under low memory conditions. | ||||||
|  |  | ||||||
|  | * September 28 2007 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Bumped version to 1.5.0 for next release and soname bumped to 2 due to ABI | ||||||
|  |   and API changes in the progress callback (and possibly more coming up from | ||||||
|  |   Steinar) | ||||||
|  |  | ||||||
|  | * September 28 2007 (Steinar H. Gunderson) | ||||||
|  |  | ||||||
|  | - Don't skip a server if it's the only one. (Bugfix from the Google tree.) | ||||||
|  |  | ||||||
|  | - Made the query callbacks receive the number of timeouts that happened during | ||||||
|  |   the execution of a query, and updated documentation accordingly. (Patch from | ||||||
|  |   the Google tree.) | ||||||
|  |  | ||||||
|  | - Support a few more socket options: ARES_OPT_SOCK_SNDBUF and | ||||||
|  |   ARES_OPT_SOCK_RCVBUF | ||||||
|  |  | ||||||
|  | - Always register for TCP events even if there are no outstanding queries, as | ||||||
|  |   the other side could always close the connection, which is a valid event | ||||||
|  |   which should be responded to. | ||||||
|  |  | ||||||
|  | * September 22 2007 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Steinar H. Gunderson fixed: Correctly clear sockets from the fd_set on in | ||||||
|  |   several functions (write_tcp_data, read_tcp_data, read_udp_packets) so that | ||||||
|  |   if it fails and the socket is closed the following code doesn't try to use | ||||||
|  |   the file descriptor. | ||||||
|  |  | ||||||
|  | - Steinar H. Gunderson modified c-ares to now also do to DNS retries even when | ||||||
|  |   TCP is used since there are several edge cases where it still makes sense. | ||||||
|  |  | ||||||
|  | - Brad House provided a fix for ares_save_options(): | ||||||
|  |  | ||||||
|  |   Apparently I overlooked something with the ares_save_options() where it | ||||||
|  |   would try to do a malloc(0) when no options of that type needed to be saved. | ||||||
|  |   On most platforms, this was fine because malloc(0) doesn't actually return | ||||||
|  |   NULL, but on AIX it does, so ares_save_options would return ARES_ENOMEM. | ||||||
|  |  | ||||||
|  | * July 14 2007 (Daniel Stenberg) | ||||||
|  |  | ||||||
|  | - Vlad Dinulescu fixed two outstanding valgrind reports: | ||||||
|  |  | ||||||
|  |   1. In ares_query.c , in find_query_by_id we compare q->qid (which is a short | ||||||
|  |   int variable) with qid, which is declared as an int variable.  Moreover, | ||||||
|  |   DNS_HEADER_SET_QID is used to set the value of qid, but DNS_HEADER_SET_QID | ||||||
|  |   sets only the first two bytes of qid. I think that qid should be declared as | ||||||
|  |   "unsigned short" in this function. | ||||||
|  |  | ||||||
|  |   2. The same problem occurs in ares_process.c, process_answer() .  query->qid | ||||||
|  |   (an unsigned short integer variable) is compared with id, which is an | ||||||
|  |   integer variable. Moreover, id is initialized from DNS_HEADER_QID which sets | ||||||
|  |   only the first two bytes of id. I think that the id variable should be | ||||||
|  |   declared as "unsigned short" in this function. | ||||||
|  |  | ||||||
|  |   Even after declaring these variables as "unsigned short", the valgrind | ||||||
|  |   errors are still there. Which brings us to the third problem. | ||||||
|  |  | ||||||
|  |   3. The third problem is that Valgrind assumes that query->qid is not | ||||||
|  |   initialised correctly. And it does that because query->qid is set from | ||||||
|  |   DNS_HEADER_QID(qbuf); Valgrind says that qbuf has unitialised bytes. And | ||||||
|  |   qbuf has uninitialised bytes because of channel->next_id . And next_id is | ||||||
|  |   set by ares_init.c:ares__generate_new_id() . I found that putting short r=0 | ||||||
|  |   in this function (instead of short r) makes all Valgrind warnings go away. | ||||||
|  |   I have studied ares__rc4() too, and this is the offending line: | ||||||
|  |  | ||||||
|  |         buffer_ptr[counter] ^= state[xorIndex];   (ares_query.c:62) | ||||||
|  |  | ||||||
|  |   This is what triggers Valgrind.. buffer_ptr is unitialised in this function, | ||||||
|  |   and by applying ^= on it, it remains unitialised. | ||||||
|  |  | ||||||
| Version 1.4.0 (June 8, 2007) | Version 1.4.0 (June 8, 2007) | ||||||
|  |  | ||||||
| * June 4 2007 (Daniel Stenberg) | * June 4 2007 (Daniel Stenberg) | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								ares/FILES
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								ares/FILES
									
									
									
									
									
								
							| @@ -1,35 +0,0 @@ | |||||||
| *.c |  | ||||||
| *.h |  | ||||||
| *.3 |  | ||||||
| NEWS |  | ||||||
| README |  | ||||||
| README.cares |  | ||||||
| CHANGES |  | ||||||
| FILES |  | ||||||
| maketgz |  | ||||||
| aclocal.m4 |  | ||||||
| acinclude.m4 |  | ||||||
| Makefile.in |  | ||||||
| Makefile.dj |  | ||||||
| Makefile.m32 |  | ||||||
| Makefile.netware |  | ||||||
| Makefile.vc6 |  | ||||||
| install-sh |  | ||||||
| mkinstalldirs |  | ||||||
| configure |  | ||||||
| configure.ac |  | ||||||
| config.guess |  | ||||||
| config.sub |  | ||||||
| vc/adig/adig.dep |  | ||||||
| vc/adig/adig.dsp |  | ||||||
| vc/adig/adig.mak |  | ||||||
| vc/adig/adig.plg |  | ||||||
| vc/vc.dsw |  | ||||||
| vc/ahost/ahost.dep |  | ||||||
| vc/ahost/ahost.dsp |  | ||||||
| vc/ahost/ahost.mak |  | ||||||
| vc/ahost/ahost.plg |  | ||||||
| vc/areslib/areslib.dep |  | ||||||
| vc/areslib/areslib.dsp |  | ||||||
| vc/areslib/areslib.mak |  | ||||||
| vc/areslib/areslib.plg |  | ||||||
| @@ -1,20 +1,56 @@ | |||||||
| AUTOMAKE_OPTIONS = foreign | AUTOMAKE_OPTIONS = foreign nostdinc | ||||||
|  |  | ||||||
|  | ACLOCAL_AMFLAGS = -I m4 | ||||||
|  |  | ||||||
|  | # Specify our include paths here, and do it relative to $(top_srcdir) and | ||||||
|  | # $(top_builddir), to ensure that these paths which belong to the library | ||||||
|  | # being currently built and tested are searched before the library which | ||||||
|  | # might possibly already be installed in the system. | ||||||
|  | # | ||||||
|  | # When using the low-level hard-hacking memory leak tracking code from | ||||||
|  | # libcurl the generated curl/curlbuild.h file must also be reachable. | ||||||
|  | # Using the libcurl lowlevel code from within c-ares library is ugly and | ||||||
|  | # only works when c-ares is built and linked with a similarly debug-build | ||||||
|  | # libcurl, but we do this anyway for convenience. | ||||||
|  | # | ||||||
|  | # $(top_builddir)/../include is for libcurl's generated curl/curlbuild.h file | ||||||
|  | # $(top_builddir) is for c-ares's generated config.h file | ||||||
|  | # $(top_srcdir) is for c-ares's lib/setup.h and other "c-ares-private" files | ||||||
|  |  | ||||||
|  | if CURLDEBUG | ||||||
|  | INCLUDES = -I$(top_builddir)/../include \ | ||||||
|  |            -I$(top_builddir)            \ | ||||||
|  |            -I$(top_srcdir) | ||||||
|  | else | ||||||
|  | INCLUDES = -I$(top_builddir) \ | ||||||
|  |            -I$(top_srcdir) | ||||||
|  | endif | ||||||
|  |  | ||||||
| lib_LTLIBRARIES = libcares.la | lib_LTLIBRARIES = libcares.la | ||||||
|  |  | ||||||
| man_MANS = $(MANPAGES) | man_MANS = $(MANPAGES) | ||||||
|  |  | ||||||
| MSVCFILES = vc/adig/adig.dep vc/adig/adig.dsp vc/vc.dsw vc/ahost/ahost.dep \ | MSVCFILES = vc/vc.dsw vc/acountry/acountry.dsp vc/adig/adig.dsp \ | ||||||
|  vc/ahost/ahost.dsp vc/areslib/areslib.dep vc/areslib/areslib.dsp	   \ |  vc/ahost/ahost.dsp vc/areslib/areslib.dsp vc/areslib/areslib.dsw | ||||||
|  vc/areslib/areslib.dsw |  | ||||||
|  | if DEBUGBUILD | ||||||
|  | PROGS = | ||||||
|  | else | ||||||
|  | PROGS = ahost adig acountry | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | noinst_PROGRAMS =$(PROGS) | ||||||
|  |  | ||||||
| # adig and ahost are just sample programs and thus not mentioned with the | # adig and ahost are just sample programs and thus not mentioned with the | ||||||
| # regular sources and headers | # regular sources and headers | ||||||
| EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \ | EXTRA_DIST = AUTHORS CHANGES README.cares Makefile.inc Makefile.dj	   \ | ||||||
|  $(MSVCFILES) AUTHORS config-win32.h RELEASE-NOTES |  Makefile.m32 Makefile.netware Makefile.vc6 $(man_MANS) $(MSVCFILES)	   \ | ||||||
|  |  config-win32.h RELEASE-NOTES libcares.pc.in buildconf get_ver.awk maketgz | ||||||
|  |  | ||||||
|  | pkgconfigdir = $(libdir)/pkgconfig | ||||||
|  | pkgconfig_DATA = libcares.pc | ||||||
|  |  | ||||||
| VER=-version-info 1:0:0 | VER=-version-info 2:0:0 | ||||||
| # This flag accepts an argument of the form current[:revision[:age]]. So, | # This flag accepts an argument of the form current[:revision[:age]]. So, | ||||||
| # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to | # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to | ||||||
| # 1. | # 1. | ||||||
| @@ -61,6 +97,15 @@ libcares_ladir = $(includedir) | |||||||
| # what headers to install on 'make install': | # what headers to install on 'make install': | ||||||
| libcares_la_HEADERS = ares.h ares_version.h ares_dns.h | libcares_la_HEADERS = ares.h ares_version.h ares_dns.h | ||||||
|  |  | ||||||
|  | ahost_SOURCES = ahost.c ares_getopt.c ares_getopt.h | ||||||
|  | ahost_LDADD = $(top_builddir)/$(lib_LTLIBRARIES) | ||||||
|  |  | ||||||
|  | adig_SOURCES = adig.c ares_getopt.c ares_getopt.h | ||||||
|  | adig_LDADD = $(top_builddir)/$(lib_LTLIBRARIES) | ||||||
|  |  | ||||||
|  | acountry_SOURCES = acountry.c ares_getopt.c ares_getopt.h | ||||||
|  | acountry_LDADD = $(top_builddir)/$(lib_LTLIBRARIES) | ||||||
|  |  | ||||||
| # Make files named *.dist replace the file without .dist extension | # Make files named *.dist replace the file without .dist extension | ||||||
| dist-hook: | dist-hook: | ||||||
| 	find $(distdir) -name "*.dist" -exec rm {} \; | 	find $(distdir) -name "*.dist" -exec rm {} \; | ||||||
|   | |||||||
| @@ -10,18 +10,25 @@ include ../packages/DOS/common.dj | |||||||
|  |  | ||||||
| include Makefile.inc | include Makefile.inc | ||||||
|  |  | ||||||
| CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_FIONBIO \ | CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \ | ||||||
|           -DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \ |           -DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \ | ||||||
|           -DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \ |           -DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \ | ||||||
|           -DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' -DHAVE_PROCESS_H \ |           -DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' \ | ||||||
|           -DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND \ |           -DHAVE_PROCESS_H -DHAVE_ARPA_NAMESER_H -DHAVE_SYS_SOCKET_H \ | ||||||
|  |           -DHAVE_SYS_UIO_H -DHAVE_NETINET_IN_H -DHAVE_NETINET_TCP_H \ | ||||||
|  |           -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND -DHAVE_GETTIMEOFDAY \ | ||||||
|           -DSEND_TYPE_ARG1='int'   -DSEND_QUAL_ARG2='const' \ |           -DSEND_TYPE_ARG1='int'   -DSEND_QUAL_ARG2='const' \ | ||||||
|           -DSEND_TYPE_ARG2='void*' -DSEND_TYPE_ARG3='int' \ |           -DSEND_TYPE_ARG2='void*' -DSEND_TYPE_ARG3='int' \ | ||||||
|           -DSEND_TYPE_ARG4='int'   -DSEND_TYPE_RETV='int' \ |           -DSEND_TYPE_ARG4='int'   -DSEND_TYPE_RETV='int' \ | ||||||
|           -DRECV_TYPE_ARG1='int'   -DRECV_TYPE_ARG2='void*' \ |           -DRECV_TYPE_ARG1='int'   -DRECV_TYPE_ARG2='void*' \ | ||||||
|           -DRECV_TYPE_ARG3='int'   -DRECV_TYPE_ARG4='int' \ |           -DRECV_TYPE_ARG3='int'   -DRECV_TYPE_ARG4='int' \ | ||||||
|           -DRECV_TYPE_RETV='int'   -DHAVE_STRUCT_TIMEVAL \ |           -DRECV_TYPE_RETV='int'   -DHAVE_STRUCT_TIMEVAL \ | ||||||
|           -Dselect=select_s        -UHAVE_CONFIG_H |           -Dselect=select_s        -Dsocklen_t=int -UHAVE_CONFIG_H \ | ||||||
|  |           -DRECVFROM_TYPE_ARG1='int' -DRECVFROM_TYPE_ARG2='void' \ | ||||||
|  |           -DRECVFROM_TYPE_ARG3='int' -DRECVFROM_TYPE_ARG4='int' \ | ||||||
|  |           -DRECVFROM_TYPE_ARG6='int' -DRECVFROM_TYPE_RETV='int' \ | ||||||
|  |           -DRECVFROM_TYPE_ARG5='struct sockaddr' -DHAVE_RECVFROM \ | ||||||
|  |           -DRECVFROM_TYPE_ARG2_IS_VOID | ||||||
|  |  | ||||||
| LDFLAGS = -s | LDFLAGS = -s | ||||||
|  |  | ||||||
| @@ -48,7 +55,7 @@ EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a | |||||||
|  |  | ||||||
| OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o)) | OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o)) | ||||||
|  |  | ||||||
| all: $(OBJ_DIR) libcares.a ahost.exe adig.exe | all: $(OBJ_DIR) libcares.a ahost.exe adig.exe acountry.exe | ||||||
| 	@echo Welcome to c-ares. | 	@echo Welcome to c-ares. | ||||||
|  |  | ||||||
| libcares.a: $(OBJECTS) | libcares.a: $(OBJECTS) | ||||||
| @@ -60,11 +67,14 @@ ahost.exe: ahost.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) | |||||||
| adig.exe: adig.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) | adig.exe: adig.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) | ||||||
| 	$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) | 	$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) | ||||||
|  |  | ||||||
|  | acountry.exe: acountry.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) | ||||||
|  | 	$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
| 	rm -f $(OBJECTS) libcares.a | 	rm -f $(OBJECTS) libcares.a | ||||||
|  |  | ||||||
| vclean realclean: clean | vclean realclean: clean | ||||||
| 	rm -f ahost.exe adig.exe depend.dj | 	rm -f ahost.exe adig.exe acountry.exe depend.dj | ||||||
| 	- rmdir $(OBJ_DIR) | 	- rmdir $(OBJ_DIR) | ||||||
|  |  | ||||||
| -include depend.dj | -include depend.dj | ||||||
|   | |||||||
| @@ -6,11 +6,11 @@ ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c		\ | |||||||
| ares_expand_name.c ares_parse_a_reply.c windows_port.c			\ | ares_expand_name.c ares_parse_a_reply.c windows_port.c			\ | ||||||
| ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c	\ | 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		\ | ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c		\ | ||||||
| ares_parse_ns_reply.c | ares_parse_ns_reply.c ares_llist.c ares__timeval.c | ||||||
|  |  | ||||||
| HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h          \ | 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  |            setup_once.h ares_llist.h | ||||||
|  |  | ||||||
| MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \ | 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_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3		    \ | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ $(LIB): $(OBJLIB) | |||||||
|  |  | ||||||
| all: $(LIB) demos | all: $(LIB) demos | ||||||
|  |  | ||||||
| demos: adig.exe ahost.exe | demos: adig.exe ahost.exe acountry.exe | ||||||
|  |  | ||||||
| tags: | tags: | ||||||
| 	etags *.[ch] | 	etags *.[ch] | ||||||
| @@ -61,7 +61,7 @@ install: | |||||||
| 	done) | 	done) | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
| 	$(RM) ares_getopt.o $(OBJLIB) $(LIB) adig.exe ahost.exe | 	$(RM) ares_getopt.o $(OBJLIB) $(LIB) adig.exe ahost.exe acountry.exe | ||||||
|  |  | ||||||
| distclean: clean | distclean: clean | ||||||
| 	$(RM) config.cache config.log config.status Makefile | 	$(RM) config.cache config.log config.status Makefile | ||||||
|   | |||||||
| @@ -14,14 +14,14 @@ NDKBASE	= c:/novell | |||||||
| endif | endif | ||||||
|  |  | ||||||
| ifndef INSTDIR | ifndef INSTDIR | ||||||
| INSTDIR	= ../curl-$(LIBCURL_VERSION_STR)-bin-nw | INSTDIR	= ../ares-$(LIBCARES_VERSION_STR)-bin-nw | ||||||
| endif | endif | ||||||
|  |  | ||||||
| # Edit the vars below to change NLM target settings. | # Edit the vars below to change NLM target settings. | ||||||
| TARGETS = adig.nlm ahost.nlm | TARGETS = adig.nlm ahost.nlm acountry.nlm | ||||||
| LTARGET = libcares.$(LIBEXT) | LTARGET = libcares.$(LIBEXT) | ||||||
| VERSION	= $(LIBCARES_VERSION) | VERSION	= $(LIBCARES_VERSION) | ||||||
| COPYR	= Copyright (C) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se> | COPYR	= Copyright (C) 1996 - 2008, Daniel Stenberg, <daniel@haxx.se> | ||||||
| DESCR	= cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se | DESCR	= cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se | ||||||
| MTSAFE	= YES | MTSAFE	= YES | ||||||
| STACK	= 64000 | STACK	= 64000 | ||||||
| @@ -63,18 +63,19 @@ else | |||||||
| 	CC = gcc | 	CC = gcc | ||||||
| endif | endif | ||||||
| # a native win32 awk can be downloaded from here: | # a native win32 awk can be downloaded from here: | ||||||
| # http://www.gknw.net/development/prgtools/awk-20050424.zip | # http://www.gknw.net/development/prgtools/awk-20070501.zip | ||||||
| AWK	= awk | AWK	= awk | ||||||
| YACC	= bison -y | YACC	= bison -y | ||||||
| CP	= cp -afv | CP	= cp -afv | ||||||
|  | MKDIR	= mkdir | ||||||
| # RM	= rm -f | # RM	= rm -f | ||||||
| # if you want to mark the target as MTSAFE you will need a tool for | # if you want to mark the target as MTSAFE you will need a tool for | ||||||
| # generating the xdc data for the linker; here's a minimal tool: | # generating the xdc data for the linker; here's a minimal tool: | ||||||
| # http://www.gknw.com/development/prgtools/mkxdc.zip | # http://www.gknw.net/development/prgtools/mkxdc.zip | ||||||
| MPKXDC	= mkxdc | MPKXDC	= mkxdc | ||||||
|  |  | ||||||
| # Global flags for all compilers | # Global flags for all compilers | ||||||
| CFLAGS	= $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc | CFLAGS	+= $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc | ||||||
|  |  | ||||||
| ifeq ($(CC),mwccnlm) | ifeq ($(CC),mwccnlm) | ||||||
| LD	= mwldnlm | LD	= mwldnlm | ||||||
| @@ -130,6 +131,9 @@ else | |||||||
| 	# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete | 	# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete | ||||||
| 	# INCLUDES += -I$(SDK_CLIB)/include | 	# INCLUDES += -I$(SDK_CLIB)/include | ||||||
| endif | endif | ||||||
|  | ifeq ($(DB),CURLDEBUG) | ||||||
|  | INCLUDES += -I../include | ||||||
|  | endif | ||||||
| CFLAGS	+= -I. $(INCLUDES) | CFLAGS	+= -I. $(INCLUDES) | ||||||
|  |  | ||||||
| ifeq ($(MTSAFE),YES) | ifeq ($(MTSAFE),YES) | ||||||
| @@ -158,10 +162,6 @@ nlm: prebuild $(TARGETS) | |||||||
|  |  | ||||||
| prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h arpa/nameser.h | prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h arpa/nameser.h | ||||||
|  |  | ||||||
| dist: all |  | ||||||
| 	-$(RM) $(OBJLIB) $(OBJDIR)/*.map $(OBJDIR)/*.ncv |  | ||||||
| 	-$(RM) $(OBJDIR)/*.def $(OBJDIR)/*.xdc $(OBJDIR)/version.inc |  | ||||||
|  |  | ||||||
| install: $(INSTDIR) all | install: $(INSTDIR) all | ||||||
| 	@$(CP) *.nlm $(INSTDIR) | 	@$(CP) *.nlm $(INSTDIR) | ||||||
| 	@$(CP) ../CHANGES $(INSTDIR) | 	@$(CP) ../CHANGES $(INSTDIR) | ||||||
| @@ -187,11 +187,8 @@ endif | |||||||
| 	@-$(RM) $@ | 	@-$(RM) $@ | ||||||
| 	@$(LD) $(LDFLAGS) $< | 	@$(LD) $(LDFLAGS) $< | ||||||
|  |  | ||||||
| $(INSTDIR): | $(OBJDIR) $(INSTDIR): | ||||||
| 	@mkdir $(INSTDIR) | 	@$(MKDIR) $@ | ||||||
|  |  | ||||||
| $(OBJDIR): |  | ||||||
| 	@mkdir $(OBJDIR) |  | ||||||
|  |  | ||||||
| $(OBJDIR)/%.o: %.c | $(OBJDIR)/%.o: %.c | ||||||
| #	@echo Compiling $< | #	@echo Compiling $< | ||||||
| @@ -199,7 +196,7 @@ $(OBJDIR)/%.o: %.c | |||||||
|  |  | ||||||
| $(OBJDIR)/version.inc: ares_version.h $(OBJDIR) | $(OBJDIR)/version.inc: ares_version.h $(OBJDIR) | ||||||
| 	@echo Creating $@ | 	@echo Creating $@ | ||||||
| 	@$(AWK) -f ../packages/NetWare/get_ver.awk $< > $@ | 	@$(AWK) -f get_ver.awk $< > $@ | ||||||
|  |  | ||||||
| $(OBJDIR)/%.xdc: Makefile.netware | $(OBJDIR)/%.xdc: Makefile.netware | ||||||
| 	@echo Creating $@ | 	@echo Creating $@ | ||||||
| @@ -266,8 +263,9 @@ ifdef IMPORTS | |||||||
| 	@echo $(DL)import $(IMPORTS)$(DL) >> $@ | 	@echo $(DL)import $(IMPORTS)$(DL) >> $@ | ||||||
| endif | endif | ||||||
| ifeq ($(LD),nlmconv) | ifeq ($(LD),nlmconv) | ||||||
| 	@echo $(DL)input $(OBJEXE)$(DL) >> $@ |  | ||||||
| 	@echo $(DL)input $(PRELUDE)$(DL) >> $@ | 	@echo $(DL)input $(PRELUDE)$(DL) >> $@ | ||||||
|  | 	@echo $(DL)input $(OBJEXE)$(DL) >> $@ | ||||||
|  | 	@echo $(DL)input $(@:.def=.o)$(DL) >> $@ | ||||||
| 	@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ | 	@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ | ||||||
| endif | endif | ||||||
|  |  | ||||||
| @@ -284,20 +282,25 @@ config.h: Makefile.netware | |||||||
| 	@echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"$(DL) >> $@ | 	@echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"$(DL) >> $@ | ||||||
| ifeq ($(LIBARCH),CLIB) | ifeq ($(LIBARCH),CLIB) | ||||||
| 	@echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@ | 	@echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@ | ||||||
| 	@echo $(DL)#define MAXHOSTNAMELEN 256$(DL) >> $@ |  | ||||||
| 	@echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@ | 	@echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_ARG2 char *$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_ARG2 char *$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_ARG3 int$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_ARG3 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_RETV int$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_RETV int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG1 int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG2 char$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG3 int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG4 int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG5 struct sockaddr$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG6 int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_RETV int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ | 	@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_ARG2 char *$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG2 char *$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define DL_LDAP_FILE "ldapsdk.nlm"$(DL) >> $@ |  | ||||||
| 	@echo $(DL)#define socklen_t int$(DL) >> $@ | 	@echo $(DL)#define socklen_t int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define strncasecmp strnicmp$(DL) >> $@ | 	@echo $(DL)#define strncasecmp strnicmp$(DL) >> $@ | ||||||
| 	@echo $(DL)#define strcasecmp stricmp$(DL) >> $@ | 	@echo $(DL)#define strcasecmp stricmp$(DL) >> $@ | ||||||
| @@ -328,6 +331,14 @@ else | |||||||
| 	@echo $(DL)#define RECV_TYPE_ARG3 size_t$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_ARG3 size_t$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RECV_TYPE_RETV ssize_t$(DL) >> $@ | 	@echo $(DL)#define RECV_TYPE_RETV ssize_t$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG1 int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG2 void$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG3 size_t$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG4 int$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG5 struct sockaddr$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG6 size_t$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_RETV ssize_t$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define RECVFROM_TYPE_ARG2_IS_VOID 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ | 	@echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_ARG2 void *$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG2 void *$(DL) >> $@ | ||||||
| @@ -335,7 +346,6 @@ else | |||||||
| 	@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SEND_TYPE_RETV ssize_t$(DL) >> $@ | 	@echo $(DL)#define SEND_TYPE_RETV ssize_t$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ | 	@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ | ||||||
| 	@echo $(DL)#define DL_LDAP_FILE "lldapsdk.nlm"$(DL) >> $@ |  | ||||||
| endif | endif | ||||||
| 	@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@ | ||||||
| @@ -354,6 +364,7 @@ endif | |||||||
| 	@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_RECV 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_RECV 1$(DL) >> $@ | ||||||
|  | 	@echo $(DL)#define HAVE_RECVFROM 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_SEND 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_SEND 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@ | ||||||
| @@ -377,7 +388,6 @@ endif | |||||||
| 	@echo $(DL)#define HAVE_UTIME 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_UTIME 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@ | 	@echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define RETSIGTYPE void$(DL) >> $@ | 	@echo $(DL)#define RETSIGTYPE void$(DL) >> $@ | ||||||
| 	@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@ |  | ||||||
| 	@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ | 	@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ | ||||||
| 	@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@ | 	@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@ | ||||||
| 	@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ | 	@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ | ||||||
|   | |||||||
| @@ -60,7 +60,9 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj              \ | |||||||
|           $(OBJ_DIR)\ares_strerror.obj         \ |           $(OBJ_DIR)\ares_strerror.obj         \ | ||||||
|           $(OBJ_DIR)\ares_cancel.obj           \ |           $(OBJ_DIR)\ares_cancel.obj           \ | ||||||
|           $(OBJ_DIR)\ares_init.obj             \ |           $(OBJ_DIR)\ares_init.obj             \ | ||||||
|  |           $(OBJ_DIR)\ares_llist.obj            \ | ||||||
|           $(OBJ_DIR)\ares_timeout.obj          \ |           $(OBJ_DIR)\ares_timeout.obj          \ | ||||||
|  |           $(OBJ_DIR)\ares__timeval.obj         \ | ||||||
|           $(OBJ_DIR)\ares_destroy.obj          \ |           $(OBJ_DIR)\ares_destroy.obj          \ | ||||||
|           $(OBJ_DIR)\ares_mkquery.obj          \ |           $(OBJ_DIR)\ares_mkquery.obj          \ | ||||||
|           $(OBJ_DIR)\ares_version.obj          \ |           $(OBJ_DIR)\ares_version.obj          \ | ||||||
| @@ -75,7 +77,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj              \ | |||||||
|           $(OBJ_DIR)\inet_net_pton.obj         \ |           $(OBJ_DIR)\inet_net_pton.obj         \ | ||||||
|           $(OBJ_DIR)\inet_ntop.obj |           $(OBJ_DIR)\inet_ntop.obj | ||||||
|  |  | ||||||
| all: $(OBJ_DIR) cares.lib cares.dll cares_imp.lib ahost.exe adig.exe | all: $(OBJ_DIR) cares.lib cares.dll cares_imp.lib ahost.exe adig.exe acountry.exe | ||||||
|        @echo Welcome to c-ares library and examples |        @echo Welcome to c-ares library and examples | ||||||
|  |  | ||||||
| $(OBJ_DIR): | $(OBJ_DIR): | ||||||
| @@ -109,6 +111,7 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6 | |||||||
|        @echo   ares_parse_ptr_reply   >> $@ |        @echo   ares_parse_ptr_reply   >> $@ | ||||||
|        @echo   ares_parse_ns_reply    >> $@ |        @echo   ares_parse_ns_reply    >> $@ | ||||||
|        @echo   ares_process           >> $@ |        @echo   ares_process           >> $@ | ||||||
|  |        @echo   ares_process_fd        >> $@ | ||||||
|        @echo   ares_query             >> $@ |        @echo   ares_query             >> $@ | ||||||
|        @echo   ares_search            >> $@ |        @echo   ares_search            >> $@ | ||||||
|        @echo   ares_strerror          >> $@ |        @echo   ares_strerror          >> $@ | ||||||
| @@ -121,7 +124,6 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6 | |||||||
|        @echo   ares_inet_pton         >> $@ |        @echo   ares_inet_pton         >> $@ | ||||||
|        @echo   ares_writev            >> $@ |        @echo   ares_writev            >> $@ | ||||||
|        @echo   ares_getnameinfo       >> $@ |        @echo   ares_getnameinfo       >> $@ | ||||||
|        @echo   ares_gettimeofday      >> $@ |  | ||||||
|        @echo   ares_parse_aaaa_reply  >> $@ |        @echo   ares_parse_aaaa_reply  >> $@ | ||||||
|  |  | ||||||
| ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib | ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib | ||||||
| @@ -130,11 +132,15 @@ ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp. | |||||||
| adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib | adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib | ||||||
|        link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS) |        link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS) | ||||||
|  |  | ||||||
|  | acountry.exe: $(OBJ_DIR) $(OBJ_DIR)\acountry.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib | ||||||
|  |        link $(LDFLAGS) -out:$@ $(OBJ_DIR)\acountry.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS) | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
|        - del $(OBJ_DIR)\*.obj *.ilk *.pdb *.pbt *.pbi *.pbo *._xe *.map |        - del $(OBJ_DIR)\*.obj *.ilk *.pdb *.pbt *.pbi *.pbo *._xe *.map | ||||||
|  |  | ||||||
| vclean realclean: clean | vclean realclean: clean | ||||||
|        - del $(DEF_FILE) cares.lib cares_imp.* cares.dll ahost.exe adig.exe |        - del $(DEF_FILE) cares.lib cares_imp.* cares.dll | ||||||
|  |        - del ahost.exe adig.exe acountry.exe | ||||||
|        - rd $(OBJ_DIR) |        - rd $(OBJ_DIR) | ||||||
|  |  | ||||||
| .c{$(OBJ_DIR)}.obj: | .c{$(OBJ_DIR)}.obj: | ||||||
| @@ -189,6 +195,9 @@ $(OBJ_DIR)\ares_init.obj: ares_init.c setup.h setup_once.h nameser.h ares.h    \ | |||||||
| $(OBJ_DIR)\ares_timeout.obj: ares_timeout.c setup.h setup_once.h ares.h        \ | $(OBJ_DIR)\ares_timeout.obj: ares_timeout.c setup.h setup_once.h ares.h        \ | ||||||
|   ares_private.h ares_ipv6.h |   ares_private.h ares_ipv6.h | ||||||
|  |  | ||||||
|  | $(OBJ_DIR)\ares__timeval.obj: ares__timeval.c setup.h setup_once.h ares.h      \ | ||||||
|  |   ares_private.h ares_ipv6.h | ||||||
|  |  | ||||||
| $(OBJ_DIR)\ares_destroy.obj: ares_destroy.c setup.h setup_once.h ares.h        \ | $(OBJ_DIR)\ares_destroy.obj: ares_destroy.c setup.h setup_once.h ares.h        \ | ||||||
|   ares_private.h ares_ipv6.h |   ares_private.h ares_ipv6.h | ||||||
|  |  | ||||||
| @@ -231,3 +240,6 @@ $(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h setup_once.h nameser.h           \ | |||||||
|   ares_ipv6.h inet_ntop.h |   ares_ipv6.h inet_ntop.h | ||||||
|  |  | ||||||
| $(OBJ_DIR)\ares_getopt.obj: ares_getopt.c ares_getopt.h | $(OBJ_DIR)\ares_getopt.obj: ares_getopt.c ares_getopt.h | ||||||
|  |  | ||||||
|  | $(OBJ_DIR)\ares_llist.obj: ares_llist.c setup.h setup_once.h ares.h            \ | ||||||
|  |   ares_private.h ares_llist.h | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ call ares_process() when select() returns. | |||||||
| Some features are missing from the current version of ares, relative | Some features are missing from the current version of ares, relative | ||||||
| to the BIND resolver: | to the BIND resolver: | ||||||
|  |  | ||||||
| 	* There is no IPV6 support. | 	* There is no IPV6 support.                [not true for c-ares] | ||||||
| 	* There is no hostname verification. | 	* There is no hostname verification. | ||||||
| 	* There is no logging of unexpected events. | 	* There is no logging of unexpected events. | ||||||
| 	* There is no debugging-oriented logging. | 	* There is no debugging-oriented logging. | ||||||
|   | |||||||
| @@ -1,9 +1,10 @@ | |||||||
| This is what's new and changed in the c-ares 1.4.1 release: | This is what's new and changed in the c-ares 1.5.4 release: | ||||||
|  |  | ||||||
|  o  |  o  | ||||||
|  |  | ||||||
| Thanks go to these friendly people for their efforts and contributions: | Thanks go to these friendly people for their efforts and contributions: | ||||||
|  |  | ||||||
|   |   | ||||||
|  |  and obviously Daniel Stenberg | ||||||
|  |  | ||||||
| Have fun! | Have fun! | ||||||
|   | |||||||
							
								
								
									
										1050
									
								
								ares/acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										1050
									
								
								ares/acinclude.m4
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										596
									
								
								ares/acountry.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										596
									
								
								ares/acountry.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,596 @@ | |||||||
|  | /* | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |  * IP-address/hostname to country converter. | ||||||
|  |  * | ||||||
|  |  * Problem; you want to know where IP a.b.c.d is located. | ||||||
|  |  * | ||||||
|  |  * Use ares_gethostbyname ("d.c.b.a.zz.countries.nerd.dk") | ||||||
|  |  * and get the CNAME (host->h_name). Result will be: | ||||||
|  |  *   CNAME = zz<CC>.countries.nerd.dk with address 127.0.x.y (ver 1) or | ||||||
|  |  *   CNAME = <a.b.c.d>.zz.countries.nerd.dk with address 127.0.x.y (ver 2) | ||||||
|  |  * | ||||||
|  |  * The 2 letter country code in <CC> and the ISO-3166 country | ||||||
|  |  * number in x.y (number = x*256 + y). Version 2 of the protocol is missing | ||||||
|  |  * the <CC> number. | ||||||
|  |  * | ||||||
|  |  * Ref: http://countries.nerd.dk/more.html | ||||||
|  |  * | ||||||
|  |  * Written by G. Vanem <gvanem@broadpark.no> 2006, 2007 | ||||||
|  |  * | ||||||
|  |  * NB! This program may not be big-endian aware. | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "setup.h" | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <ctype.h> | ||||||
|  | #ifdef HAVE_UNISTD_H | ||||||
|  | #include <unistd.h> | ||||||
|  | #endif | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(WIN32) && !defined(WATT32) | ||||||
|  |   #include <winsock.h> | ||||||
|  | #else | ||||||
|  |   #include <arpa/inet.h> | ||||||
|  |   #include <netinet/in.h> | ||||||
|  |   #include <netdb.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "ares.h" | ||||||
|  | #include "ares_getopt.h" | ||||||
|  | #include "inet_net_pton.h" | ||||||
|  | #include "inet_ntop.h" | ||||||
|  |  | ||||||
|  | #ifndef INADDR_NONE | ||||||
|  | #define INADDR_NONE 0xffffffff | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static const char *usage      = "acountry [-vh?] {host|addr} ...\n"; | ||||||
|  | static const char  nerd_fmt[] = "%u.%u.%u.%u.zz.countries.nerd.dk"; | ||||||
|  | static const char *nerd_ver1  = nerd_fmt + 14; | ||||||
|  | static const char *nerd_ver2  = nerd_fmt + 11; | ||||||
|  | static int         verbose    = 0; | ||||||
|  |  | ||||||
|  | #define TRACE(fmt) do {               \ | ||||||
|  |                      if (verbose > 0) \ | ||||||
|  |                        printf fmt ;   \ | ||||||
|  |                    } while (0) | ||||||
|  |  | ||||||
|  | static void wait_ares(ares_channel channel); | ||||||
|  | static void callback(void *arg, int status, int timeouts, struct hostent *host); | ||||||
|  | static void callback2(void *arg, int status, int timeouts, struct hostent *host); | ||||||
|  | static void find_country_from_cname(const char *cname, struct in_addr addr); | ||||||
|  |  | ||||||
|  | static void Abort(const char *fmt, ...) | ||||||
|  | { | ||||||
|  |   va_list args; | ||||||
|  |   va_start(args, fmt); | ||||||
|  |   vfprintf(stderr, fmt, args); | ||||||
|  |   va_end(args); | ||||||
|  |   exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, char **argv) | ||||||
|  | { | ||||||
|  |   ares_channel channel; | ||||||
|  |   int    ch, status; | ||||||
|  |  | ||||||
|  | #if defined(WIN32) && !defined(WATT32) | ||||||
|  |   WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK); | ||||||
|  |   WSADATA wsaData; | ||||||
|  |   WSAStartup(wVersionRequested, &wsaData); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   while ((ch = ares_getopt(argc, argv, "dvh?")) != -1) | ||||||
|  |     switch (ch) | ||||||
|  |       { | ||||||
|  |       case 'd': | ||||||
|  | #ifdef WATT32 | ||||||
|  |         dbug_init(); | ||||||
|  | #endif | ||||||
|  |         break; | ||||||
|  |       case 'v': | ||||||
|  |         verbose++; | ||||||
|  |         break; | ||||||
|  |       case 'h': | ||||||
|  |       case '?': | ||||||
|  |       default: | ||||||
|  |         Abort(usage); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |   argc -= optind; | ||||||
|  |   argv += optind; | ||||||
|  |   if (argc < 1) | ||||||
|  |      Abort(usage); | ||||||
|  |  | ||||||
|  |   status = ares_init(&channel); | ||||||
|  |   if (status != ARES_SUCCESS) | ||||||
|  |     { | ||||||
|  |       fprintf(stderr, "ares_init: %s\n", ares_strerror(status)); | ||||||
|  |       return 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* Initiate the queries, one per command-line argument. */ | ||||||
|  |   for ( ; *argv; argv++) | ||||||
|  |     { | ||||||
|  |       struct in_addr addr; | ||||||
|  |       char buf[100]; | ||||||
|  |  | ||||||
|  |       /* If this fails, assume '*argv' is a host-name that | ||||||
|  |        * must be resolved first | ||||||
|  |        */ | ||||||
|  |       if (ares_inet_pton(AF_INET, *argv, &addr) != 1) | ||||||
|  |         { | ||||||
|  |           ares_gethostbyname(channel, *argv, AF_INET, callback2, &addr); | ||||||
|  |           wait_ares(channel); | ||||||
|  |           if (addr.s_addr == INADDR_NONE) | ||||||
|  |             { | ||||||
|  |               printf("Failed to lookup %s\n", *argv); | ||||||
|  |               continue; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       sprintf(buf, nerd_fmt, | ||||||
|  |               (unsigned int)(addr.s_addr >> 24), | ||||||
|  |               (unsigned int)((addr.s_addr >> 16) & 255), | ||||||
|  |               (unsigned int)((addr.s_addr >> 8) & 255), | ||||||
|  |               (unsigned int)(addr.s_addr & 255)); | ||||||
|  |       TRACE(("Looking up %s...", buf)); | ||||||
|  |       fflush(stdout); | ||||||
|  |       ares_gethostbyname(channel, buf, AF_INET, callback, buf); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   wait_ares(channel); | ||||||
|  |   ares_destroy(channel); | ||||||
|  |  | ||||||
|  | #if defined(WIN32) && !defined(WATT32) | ||||||
|  |   WSACleanup(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Wait for the queries to complete. | ||||||
|  |  */ | ||||||
|  | static void wait_ares(ares_channel channel) | ||||||
|  | { | ||||||
|  |   while (1) | ||||||
|  |     { | ||||||
|  |       struct timeval *tvp, tv; | ||||||
|  |       fd_set read_fds, write_fds; | ||||||
|  |       int nfds; | ||||||
|  |  | ||||||
|  |       FD_ZERO(&read_fds); | ||||||
|  |       FD_ZERO(&write_fds); | ||||||
|  |       nfds = ares_fds(channel, &read_fds, &write_fds); | ||||||
|  |       if (nfds == 0) | ||||||
|  |         break; | ||||||
|  |       tvp = ares_timeout(channel, NULL, &tv); | ||||||
|  |       select(nfds, &read_fds, &write_fds, NULL, tvp); | ||||||
|  |       ares_process(channel, &read_fds, &write_fds); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * This is the callback used when we have the IP-address of interest. | ||||||
|  |  * Extract the CNAME and figure out the country-code from it. | ||||||
|  |  */ | ||||||
|  | static void callback(void *arg, int status, int timeouts, struct hostent *host) | ||||||
|  | { | ||||||
|  |   const char *name = (const char*)arg; | ||||||
|  |   const char *cname; | ||||||
|  |   char buf[20]; | ||||||
|  |  | ||||||
|  |   (void)timeouts; | ||||||
|  |  | ||||||
|  |   if (!host || status != ARES_SUCCESS) | ||||||
|  |     { | ||||||
|  |       printf("Failed to lookup %s: %s\n", name, ares_strerror(status)); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   TRACE(("\nFound address %s, name %s\n", | ||||||
|  |          ares_inet_ntop(AF_INET,(const char*)host->h_addr,buf,sizeof(buf)), | ||||||
|  |          host->h_name)); | ||||||
|  |  | ||||||
|  |   cname = host->h_name;  /* CNAME gets put here */ | ||||||
|  |   if (!cname) | ||||||
|  |     printf("Failed to get CNAME for %s\n", name); | ||||||
|  |   else | ||||||
|  |     find_country_from_cname(cname, *(struct in_addr*)host->h_addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * This is the callback used to obtain the IP-address of the host of interest. | ||||||
|  |  */ | ||||||
|  | static void callback2(void *arg, int status, int timeouts, struct hostent *host) | ||||||
|  | { | ||||||
|  |   struct in_addr *addr = (struct in_addr*) arg; | ||||||
|  |  | ||||||
|  |   (void)timeouts; | ||||||
|  |   if (!host || status != ARES_SUCCESS) | ||||||
|  |     memset(addr, INADDR_NONE, sizeof(*addr)); | ||||||
|  |   else | ||||||
|  |     memcpy(addr, host->h_addr, sizeof(*addr)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct search_list { | ||||||
|  |        int         country_number; /* ISO-3166 country number */ | ||||||
|  |        char        short_name[3];  /* A2 short country code */ | ||||||
|  |        const char *long_name;      /* normal country name */ | ||||||
|  |      }; | ||||||
|  |  | ||||||
|  | const struct search_list *list_lookup(int number, const struct search_list *list, int num) | ||||||
|  | { | ||||||
|  |   while (num > 0 && list->long_name) | ||||||
|  |     { | ||||||
|  |       if (list->country_number == number) | ||||||
|  |         return (list); | ||||||
|  |       num--; | ||||||
|  |       list++; | ||||||
|  |     } | ||||||
|  |   return (NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Ref: ftp://ftp.ripe.net/iso3166-countrycodes.txt | ||||||
|  |  */ | ||||||
|  | static const struct search_list country_list[] = { | ||||||
|  |        {   4, "af", "Afghanistan"                          }, | ||||||
|  |        { 248, "ax", "<EFBFBD>land Island"                         }, | ||||||
|  |        {   8, "al", "Albania"                              }, | ||||||
|  |        {  12, "dz", "Algeria"                              }, | ||||||
|  |        {  16, "as", "American Samoa"                       }, | ||||||
|  |        {  20, "ad", "Andorra"                              }, | ||||||
|  |        {  24, "ao", "Angola"                               }, | ||||||
|  |        { 660, "ai", "Anguilla"                             }, | ||||||
|  |        {  10, "aq", "Antarctica"                           }, | ||||||
|  |        {  28, "ag", "Antigua & Barbuda"                    }, | ||||||
|  |        {  32, "ar", "Argentina"                            }, | ||||||
|  |        {  51, "am", "Armenia"                              }, | ||||||
|  |        { 533, "aw", "Aruba"                                }, | ||||||
|  |        {  36, "au", "Australia"                            }, | ||||||
|  |        {  40, "at", "Austria"                              }, | ||||||
|  |        {  31, "az", "Azerbaijan"                           }, | ||||||
|  |        {  44, "bs", "Bahamas"                              }, | ||||||
|  |        {  48, "bh", "Bahrain"                              }, | ||||||
|  |        {  50, "bd", "Bangladesh"                           }, | ||||||
|  |        {  52, "bb", "Barbados"                             }, | ||||||
|  |        { 112, "by", "Belarus"                              }, | ||||||
|  |        {  56, "be", "Belgium"                              }, | ||||||
|  |        {  84, "bz", "Belize"                               }, | ||||||
|  |        { 204, "bj", "Benin"                                }, | ||||||
|  |        {  60, "bm", "Bermuda"                              }, | ||||||
|  |        {  64, "bt", "Bhutan"                               }, | ||||||
|  |        {  68, "bo", "Bolivia"                              }, | ||||||
|  |        {  70, "ba", "Bosnia & Herzegowina"                 }, | ||||||
|  |        {  72, "bw", "Botswana"                             }, | ||||||
|  |        {  74, "bv", "Bouvet Island"                        }, | ||||||
|  |        {  76, "br", "Brazil"                               }, | ||||||
|  |        {  86, "io", "British Indian Ocean Territory"       }, | ||||||
|  |        {  96, "bn", "Brunei Darussalam"                    }, | ||||||
|  |        { 100, "bg", "Bulgaria"                             }, | ||||||
|  |        { 854, "bf", "Burkina Faso"                         }, | ||||||
|  |        { 108, "bi", "Burundi"                              }, | ||||||
|  |        { 116, "kh", "Cambodia"                             }, | ||||||
|  |        { 120, "cm", "Cameroon"                             }, | ||||||
|  |        { 124, "ca", "Canada"                               }, | ||||||
|  |        { 132, "cv", "Cape Verde"                           }, | ||||||
|  |        { 136, "ky", "Cayman Islands"                       }, | ||||||
|  |        { 140, "cf", "Central African Republic"             }, | ||||||
|  |        { 148, "td", "Chad"                                 }, | ||||||
|  |        { 152, "cl", "Chile"                                }, | ||||||
|  |        { 156, "cn", "China"                                }, | ||||||
|  |        { 162, "cx", "Christmas Island"                     }, | ||||||
|  |        { 166, "cc", "Cocos Islands"                        }, | ||||||
|  |        { 170, "co", "Colombia"                             }, | ||||||
|  |        { 174, "km", "Comoros"                              }, | ||||||
|  |        { 178, "cg", "Congo"                                }, | ||||||
|  |        { 180, "cd", "Congo"                                }, | ||||||
|  |        { 184, "ck", "Cook Islands"                         }, | ||||||
|  |        { 188, "cr", "Costa Rica"                           }, | ||||||
|  |        { 384, "ci", "Cote d'Ivoire"                        }, | ||||||
|  |        { 191, "hr", "Croatia"                              }, | ||||||
|  |        { 192, "cu", "Cuba"                                 }, | ||||||
|  |        { 196, "cy", "Cyprus"                               }, | ||||||
|  |        { 203, "cz", "Czech Republic"                       }, | ||||||
|  |        { 208, "dk", "Denmark"                              }, | ||||||
|  |        { 262, "dj", "Djibouti"                             }, | ||||||
|  |        { 212, "dm", "Dominica"                             }, | ||||||
|  |        { 214, "do", "Dominican Republic"                   }, | ||||||
|  |        { 218, "ec", "Ecuador"                              }, | ||||||
|  |        { 818, "eg", "Egypt"                                }, | ||||||
|  |        { 222, "sv", "El Salvador"                          }, | ||||||
|  |        { 226, "gq", "Equatorial Guinea"                    }, | ||||||
|  |        { 232, "er", "Eritrea"                              }, | ||||||
|  |        { 233, "ee", "Estonia"                              }, | ||||||
|  |        { 231, "et", "Ethiopia"                             }, | ||||||
|  |        { 238, "fk", "Falkland Islands"                     }, | ||||||
|  |        { 234, "fo", "Faroe Islands"                        }, | ||||||
|  |        { 242, "fj", "Fiji"                                 }, | ||||||
|  |        { 246, "fi", "Finland"                              }, | ||||||
|  |        { 250, "fr", "France"                               }, | ||||||
|  |        { 249, "fx", "France, Metropolitan"                 }, | ||||||
|  |        { 254, "gf", "French Guiana"                        }, | ||||||
|  |        { 258, "pf", "French Polynesia"                     }, | ||||||
|  |        { 260, "tf", "French Southern Territories"          }, | ||||||
|  |        { 266, "ga", "Gabon"                                }, | ||||||
|  |        { 270, "gm", "Gambia"                               }, | ||||||
|  |        { 268, "ge", "Georgia"                              }, | ||||||
|  |        { 276, "de", "Germany"                              }, | ||||||
|  |        { 288, "gh", "Ghana"                                }, | ||||||
|  |        { 292, "gi", "Gibraltar"                            }, | ||||||
|  |        { 300, "gr", "Greece"                               }, | ||||||
|  |        { 304, "gl", "Greenland"                            }, | ||||||
|  |        { 308, "gd", "Grenada"                              }, | ||||||
|  |        { 312, "gp", "Guadeloupe"                           }, | ||||||
|  |        { 316, "gu", "Guam"                                 }, | ||||||
|  |        { 320, "gt", "Guatemala"                            }, | ||||||
|  |        { 324, "gn", "Guinea"                               }, | ||||||
|  |        { 624, "gw", "Guinea-Bissau"                        }, | ||||||
|  |        { 328, "gy", "Guyana"                               }, | ||||||
|  |        { 332, "ht", "Haiti"                                }, | ||||||
|  |        { 334, "hm", "Heard & Mc Donald Islands"            }, | ||||||
|  |        { 336, "va", "Vatican City"                         }, | ||||||
|  |        { 340, "hn", "Honduras"                             }, | ||||||
|  |        { 344, "hk", "Hong kong"                            }, | ||||||
|  |        { 348, "hu", "Hungary"                              }, | ||||||
|  |        { 352, "is", "Iceland"                              }, | ||||||
|  |        { 356, "in", "India"                                }, | ||||||
|  |        { 360, "id", "Indonesia"                            }, | ||||||
|  |        { 364, "ir", "Iran"                                 }, | ||||||
|  |        { 368, "iq", "Iraq"                                 }, | ||||||
|  |        { 372, "ie", "Ireland"                              }, | ||||||
|  |        { 376, "il", "Israel"                               }, | ||||||
|  |        { 380, "it", "Italy"                                }, | ||||||
|  |        { 388, "jm", "Jamaica"                              }, | ||||||
|  |        { 392, "jp", "Japan"                                }, | ||||||
|  |        { 400, "jo", "Jordan"                               }, | ||||||
|  |        { 398, "kz", "Kazakhstan"                           }, | ||||||
|  |        { 404, "ke", "Kenya"                                }, | ||||||
|  |        { 296, "ki", "Kiribati"                             }, | ||||||
|  |        { 408, "kp", "Korea (north)"                        }, | ||||||
|  |        { 410, "kr", "Korea (south)"                        }, | ||||||
|  |        { 414, "kw", "Kuwait"                               }, | ||||||
|  |        { 417, "kg", "Kyrgyzstan"                           }, | ||||||
|  |        { 418, "la", "Laos"                                 }, | ||||||
|  |        { 428, "lv", "Latvia"                               }, | ||||||
|  |        { 422, "lb", "Lebanon"                              }, | ||||||
|  |        { 426, "ls", "Lesotho"                              }, | ||||||
|  |        { 430, "lr", "Liberia"                              }, | ||||||
|  |        { 434, "ly", "Libya"                                }, | ||||||
|  |        { 438, "li", "Liechtenstein"                        }, | ||||||
|  |        { 440, "lt", "Lithuania"                            }, | ||||||
|  |        { 442, "lu", "Luxembourg"                           }, | ||||||
|  |        { 446, "mo", "Macao"                                }, | ||||||
|  |        { 807, "mk", "Macedonia"                            }, | ||||||
|  |        { 450, "mg", "Madagascar"                           }, | ||||||
|  |        { 454, "mw", "Malawi"                               }, | ||||||
|  |        { 458, "my", "Malaysia"                             }, | ||||||
|  |        { 462, "mv", "Maldives"                             }, | ||||||
|  |        { 466, "ml", "Mali"                                 }, | ||||||
|  |        { 470, "mt", "Malta"                                }, | ||||||
|  |        { 584, "mh", "Marshall Islands"                     }, | ||||||
|  |        { 474, "mq", "Martinique"                           }, | ||||||
|  |        { 478, "mr", "Mauritania"                           }, | ||||||
|  |        { 480, "mu", "Mauritius"                            }, | ||||||
|  |        { 175, "yt", "Mayotte"                              }, | ||||||
|  |        { 484, "mx", "Mexico"                               }, | ||||||
|  |        { 583, "fm", "Micronesia"                           }, | ||||||
|  |        { 498, "md", "Moldova"                              }, | ||||||
|  |        { 492, "mc", "Monaco"                               }, | ||||||
|  |        { 496, "mn", "Mongolia"                             }, | ||||||
|  |        { 500, "ms", "Montserrat"                           }, | ||||||
|  |        { 504, "ma", "Morocco"                              }, | ||||||
|  |        { 508, "mz", "Mozambique"                           }, | ||||||
|  |        { 104, "mm", "Myanmar"                              }, | ||||||
|  |        { 516, "na", "Namibia"                              }, | ||||||
|  |        { 520, "nr", "Nauru"                                }, | ||||||
|  |        { 524, "np", "Nepal"                                }, | ||||||
|  |        { 528, "nl", "Netherlands"                          }, | ||||||
|  |        { 530, "an", "Netherlands Antilles"                 }, | ||||||
|  |        { 540, "nc", "New Caledonia"                        }, | ||||||
|  |        { 554, "nz", "New Zealand"                          }, | ||||||
|  |        { 558, "ni", "Nicaragua"                            }, | ||||||
|  |        { 562, "ne", "Niger"                                }, | ||||||
|  |        { 566, "ng", "Nigeria"                              }, | ||||||
|  |        { 570, "nu", "Niue"                                 }, | ||||||
|  |        { 574, "nf", "Norfolk Island"                       }, | ||||||
|  |        { 580, "mp", "Northern Mariana Islands"             }, | ||||||
|  |        { 578, "no", "Norway"                               }, | ||||||
|  |        { 512, "om", "Oman"                                 }, | ||||||
|  |        { 586, "pk", "Pakistan"                             }, | ||||||
|  |        { 585, "pw", "Palau"                                }, | ||||||
|  |        { 275, "ps", "Palestinian Territory"                }, | ||||||
|  |        { 591, "pa", "Panama"                               }, | ||||||
|  |        { 598, "pg", "Papua New Guinea"                     }, | ||||||
|  |        { 600, "py", "Paraguay"                             }, | ||||||
|  |        { 604, "pe", "Peru"                                 }, | ||||||
|  |        { 608, "ph", "Philippines"                          }, | ||||||
|  |        { 612, "pn", "Pitcairn"                             }, | ||||||
|  |        { 616, "pl", "Poland"                               }, | ||||||
|  |        { 620, "pt", "Portugal"                             }, | ||||||
|  |        { 630, "pr", "Puerto Rico"                          }, | ||||||
|  |        { 634, "qa", "Qatar"                                }, | ||||||
|  |        { 638, "re", "Reunion"                              }, | ||||||
|  |        { 642, "ro", "Romania"                              }, | ||||||
|  |        { 643, "ru", "Russia"                               }, | ||||||
|  |        { 646, "rw", "Rwanda"                               }, | ||||||
|  |        { 659, "kn", "Saint Kitts & Nevis"                  }, | ||||||
|  |        { 662, "lc", "Saint Lucia"                          }, | ||||||
|  |        { 670, "vc", "Saint Vincent"                        }, | ||||||
|  |        { 882, "ws", "Samoa"                                }, | ||||||
|  |        { 674, "sm", "San Marino"                           }, | ||||||
|  |        { 678, "st", "Sao Tome & Principe"                  }, | ||||||
|  |        { 682, "sa", "Saudi Arabia"                         }, | ||||||
|  |        { 686, "sn", "Senegal"                              }, | ||||||
|  |        { 891, "cs", "Serbia and Montenegro"                }, | ||||||
|  |        { 690, "sc", "Seychelles"                           }, | ||||||
|  |        { 694, "sl", "Sierra Leone"                         }, | ||||||
|  |        { 702, "sg", "Singapore"                            }, | ||||||
|  |        { 703, "sk", "Slovakia"                             }, | ||||||
|  |        { 705, "si", "Slovenia"                             }, | ||||||
|  |        {  90, "sb", "Solomon Islands"                      }, | ||||||
|  |        { 706, "so", "Somalia"                              }, | ||||||
|  |        { 710, "za", "South Africa"                         }, | ||||||
|  |        { 239, "gs", "South Georgia"                        }, | ||||||
|  |        { 724, "es", "Spain"                                }, | ||||||
|  |        { 144, "lk", "Sri Lanka"                            }, | ||||||
|  |        { 654, "sh", "St. Helena"                           }, | ||||||
|  |        { 666, "pm", "St. Pierre & Miquelon"                }, | ||||||
|  |        { 736, "sd", "Sudan"                                }, | ||||||
|  |        { 740, "sr", "Suriname"                             }, | ||||||
|  |        { 744, "sj", "Svalbard & Jan Mayen Islands"         }, | ||||||
|  |        { 748, "sz", "Swaziland"                            }, | ||||||
|  |        { 752, "se", "Sweden"                               }, | ||||||
|  |        { 756, "ch", "Switzerland"                          }, | ||||||
|  |        { 760, "sy", "Syrian Arab Republic"                 }, | ||||||
|  |        { 626, "tl", "Timor-Leste"                          }, | ||||||
|  |        { 158, "tw", "Taiwan"                               }, | ||||||
|  |        { 762, "tj", "Tajikistan"                           }, | ||||||
|  |        { 834, "tz", "Tanzania"                             }, | ||||||
|  |        { 764, "th", "Thailand"                             }, | ||||||
|  |        { 768, "tg", "Togo"                                 }, | ||||||
|  |        { 772, "tk", "Tokelau"                              }, | ||||||
|  |        { 776, "to", "Tonga"                                }, | ||||||
|  |        { 780, "tt", "Trinidad & Tobago"                    }, | ||||||
|  |        { 788, "tn", "Tunisia"                              }, | ||||||
|  |        { 792, "tr", "Turkey"                               }, | ||||||
|  |        { 795, "tm", "Turkmenistan"                         }, | ||||||
|  |        { 796, "tc", "Turks & Caicos Islands"               }, | ||||||
|  |        { 798, "tv", "Tuvalu"                               }, | ||||||
|  |        { 800, "ug", "Uganda"                               }, | ||||||
|  |        { 804, "ua", "Ukraine"                              }, | ||||||
|  |        { 784, "ae", "United Arab Emirates"                 }, | ||||||
|  |        { 826, "gb", "United Kingdom"                       }, | ||||||
|  |        { 840, "us", "United States"                        }, | ||||||
|  |        { 581, "um", "United States Minor Outlying Islands" }, | ||||||
|  |        { 858, "uy", "Uruguay"                              }, | ||||||
|  |        { 860, "uz", "Uzbekistan"                           }, | ||||||
|  |        { 548, "vu", "Vanuatu"                              }, | ||||||
|  |        { 862, "ve", "Venezuela"                            }, | ||||||
|  |        { 704, "vn", "Vietnam"                              }, | ||||||
|  |        {  92, "vg", "Virgin Islands (British)"             }, | ||||||
|  |        { 850, "vi", "Virgin Islands (US)"                  }, | ||||||
|  |        { 876, "wf", "Wallis & Futuna Islands"              }, | ||||||
|  |        { 732, "eh", "Western Sahara"                       }, | ||||||
|  |        { 887, "ye", "Yemen"                                }, | ||||||
|  |        { 894, "zm", "Zambia"                               }, | ||||||
|  |        { 716, "zw", "Zimbabwe"                             } | ||||||
|  |      }; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Check if start of 'str' is simply an IPv4 address. | ||||||
|  |  */ | ||||||
|  | #define BYTE_OK(x) ((x) >= 0 && (x) <= 255) | ||||||
|  |  | ||||||
|  | static int is_addr(char *str, char **end) | ||||||
|  | { | ||||||
|  |   int a0, a1, a2, a3, num, rc = 0, length = 0; | ||||||
|  |  | ||||||
|  |   if ((num = sscanf(str,"%3d.%3d.%3d.%3d%n",&a0,&a1,&a2,&a3,&length)) == 4 && | ||||||
|  |       BYTE_OK(a0) && BYTE_OK(a1) && BYTE_OK(a2) && BYTE_OK(a3) && | ||||||
|  |       length >= (3+4)) | ||||||
|  |     { | ||||||
|  |       rc = 1; | ||||||
|  |       *end = str + length; | ||||||
|  |     } | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Find the country-code and name from the CNAME. E.g.: | ||||||
|  |  *   version 1: CNAME = zzno.countries.nerd.dk with address 127.0.2.66 | ||||||
|  |  *              yields ccode_A" = "no" and cnumber 578 (2.66). | ||||||
|  |  *   version 2: CNAME = <a.b.c.d>.zz.countries.nerd.dk with address 127.0.2.66 | ||||||
|  |  *              yields cnumber 578 (2.66). ccode_A is ""; | ||||||
|  |  */ | ||||||
|  | static void find_country_from_cname(const char *cname, struct in_addr addr) | ||||||
|  | { | ||||||
|  |   const struct search_list *country; | ||||||
|  |   char  ccode_A2[3], *ccopy, *dot_4; | ||||||
|  |   int   cnumber, z0, z1, ver_1, ver_2; | ||||||
|  |   u_long ip; | ||||||
|  |  | ||||||
|  |   ip = ntohl(addr.s_addr); | ||||||
|  |   z0 = tolower(cname[0]); | ||||||
|  |   z1 = tolower(cname[1]); | ||||||
|  |   ccopy = strdup(cname); | ||||||
|  |  | ||||||
|  |   ver_1 = (z0 == 'z' && z1 == 'z' && !strcasecmp(cname+4,nerd_ver1)); | ||||||
|  |   ver_2 = (is_addr(ccopy,&dot_4) && !strcasecmp(dot_4,nerd_ver2)); | ||||||
|  |  | ||||||
|  |   if (ver_1) | ||||||
|  |     { | ||||||
|  |       const char *dot = strchr(cname, '.'); | ||||||
|  |       if ((z0 != 'z' && z1 != 'z') || dot != cname+4) | ||||||
|  |         { | ||||||
|  |           printf("Unexpected CNAME %s (ver_1)\n", cname); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |   else if (ver_2) | ||||||
|  |     { | ||||||
|  |       z0 = tolower(dot_4[1]); | ||||||
|  |       z1 = tolower(dot_4[2]); | ||||||
|  |       if (z0 != 'z' && z1 != 'z') | ||||||
|  |         { | ||||||
|  |           printf("Unexpected CNAME %s (ver_2)\n", cname); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       printf("Unexpected CNAME %s (ver?)\n", cname); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (ver_1) | ||||||
|  |     { | ||||||
|  |       ccode_A2[0] = tolower(cname[2]); | ||||||
|  |       ccode_A2[1] = tolower(cname[3]); | ||||||
|  |       ccode_A2[2] = '\0'; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     ccode_A2[0] = '\0'; | ||||||
|  |  | ||||||
|  |   cnumber = ip & 0xFFFF; | ||||||
|  |  | ||||||
|  |   TRACE(("Found country-code `%s', number %d\n", | ||||||
|  |          ver_1 ? ccode_A2 : "<n/a>", cnumber)); | ||||||
|  |  | ||||||
|  |   country = list_lookup(cnumber, country_list, | ||||||
|  |                         sizeof(country_list) / sizeof(country_list[0])); | ||||||
|  |   if (!country) | ||||||
|  |     printf("Name for country-number %d not found.\n", cnumber); | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       if (ver_1 && *(unsigned short*)&country->short_name != *(unsigned*)&ccode_A2) | ||||||
|  |         printf("short-name mismatch; %s vs %s\n", country->short_name, ccode_A2); | ||||||
|  |  | ||||||
|  |       printf("%s (%s), number %d.\n", | ||||||
|  |              country->long_name, country->short_name, cnumber); | ||||||
|  |     } | ||||||
|  |   free(ccopy); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								ares/adig.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								ares/adig.c
									
									
									
									
									
								
							| @@ -27,11 +27,17 @@ | |||||||
| #include <netinet/in.h> | #include <netinet/in.h> | ||||||
| #include <arpa/inet.h> | #include <arpa/inet.h> | ||||||
| #include <arpa/nameser.h> | #include <arpa/nameser.h> | ||||||
|  | #ifdef HAVE_ARPA_NAMESER_COMPAT_H | ||||||
|  | #include <arpa/nameser_compat.h> | ||||||
|  | #endif | ||||||
| #ifdef HAVE_UNISTD_H | #ifdef HAVE_UNISTD_H | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #endif | #endif | ||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
| #endif | #endif | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| @@ -110,6 +116,7 @@ static const struct nv types[] = { | |||||||
|   { "AXFR",     T_AXFR }, |   { "AXFR",     T_AXFR }, | ||||||
|   { "MAILB",    T_MAILB }, |   { "MAILB",    T_MAILB }, | ||||||
|   { "MAILA",    T_MAILA }, |   { "MAILA",    T_MAILA }, | ||||||
|  |   { "NAPTR",    T_NAPTR }, | ||||||
|   { "ANY",      T_ANY } |   { "ANY",      T_ANY } | ||||||
| }; | }; | ||||||
| static const int ntypes = sizeof(types) / sizeof(types[0]); | static const int ntypes = sizeof(types) / sizeof(types[0]); | ||||||
| @@ -127,7 +134,8 @@ static const char *rcodes[] = { | |||||||
|   "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE" |   "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE" | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void callback(void *arg, int status, unsigned char *abuf, int alen); | static void callback(void *arg, int status, int timeouts, | ||||||
|  |                      unsigned char *abuf, int alen); | ||||||
| static const unsigned char *display_question(const unsigned char *aptr, | static const unsigned char *display_question(const unsigned char *aptr, | ||||||
|                                              const unsigned char *abuf, |                                              const unsigned char *abuf, | ||||||
|                                              int alen); |                                              int alen); | ||||||
| @@ -294,13 +302,16 @@ int main(int argc, char **argv) | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void callback(void *arg, int status, unsigned char *abuf, int alen) | static void callback(void *arg, int status, int timeouts, | ||||||
|  |                      unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   char *name = (char *) arg; |   char *name = (char *) arg; | ||||||
|   int id, qr, opcode, aa, tc, rd, ra, rcode; |   int id, qr, opcode, aa, tc, rd, ra, rcode; | ||||||
|   unsigned int qdcount, ancount, nscount, arcount, i; |   unsigned int qdcount, ancount, nscount, arcount, i; | ||||||
|   const unsigned char *aptr; |   const unsigned char *aptr; | ||||||
|  |  | ||||||
|  |   (void) timeouts; | ||||||
|  |  | ||||||
|   /* Display the query name if given. */ |   /* Display the query name if given. */ | ||||||
|   if (name) |   if (name) | ||||||
|     printf("Answer for query %s:\n", name); |     printf("Answer for query %s:\n", name); | ||||||
| @@ -601,6 +612,41 @@ static const unsigned char *display_rr(const unsigned char *aptr, | |||||||
|       ares_free_string(name); |       ares_free_string(name); | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|  |     case T_NAPTR: | ||||||
|  |  | ||||||
|  |       printf("\t%d", DNS__16BIT(aptr)); /* order */ | ||||||
|  |       printf(" %d\n", DNS__16BIT(aptr + 2)); /* preference */ | ||||||
|  |  | ||||||
|  |       p = aptr + 4; | ||||||
|  |       status = ares_expand_string(p, abuf, alen, (unsigned char **)&name, &len); | ||||||
|  |       if (status != ARES_SUCCESS) | ||||||
|  |         return NULL; | ||||||
|  |       printf("\t\t\t\t\t\t%s\n", name); | ||||||
|  |       ares_free_string(name); | ||||||
|  |       p += len; | ||||||
|  |  | ||||||
|  |       status = ares_expand_string(p, abuf, alen, (unsigned char **)&name, &len); | ||||||
|  |       if (status != ARES_SUCCESS) | ||||||
|  |         return NULL; | ||||||
|  |       printf("\t\t\t\t\t\t%s\n", name); | ||||||
|  |       ares_free_string(name); | ||||||
|  |       p += len; | ||||||
|  |  | ||||||
|  |       status = ares_expand_string(p, abuf, alen, (unsigned char **)&name, &len); | ||||||
|  |       if (status != ARES_SUCCESS) | ||||||
|  |         return NULL; | ||||||
|  |       printf("\t\t\t\t\t\t%s\n", name); | ||||||
|  |       ares_free_string(name); | ||||||
|  |       p += len; | ||||||
|  |  | ||||||
|  |       status = ares_expand_string(p, abuf, alen, (unsigned char **)&name, &len); | ||||||
|  |       if (status != ARES_SUCCESS) | ||||||
|  |         return NULL; | ||||||
|  |       printf("\t\t\t\t\t\t%s", name); | ||||||
|  |       ares_free_string(name); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
|       printf("\t[Unknown RR; cannot parse]"); |       printf("\t[Unknown RR; cannot parse]"); | ||||||
|       break; |       break; | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								ares/ahost.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								ares/ahost.c
									
									
									
									
									
								
							| @@ -29,6 +29,9 @@ | |||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| @@ -40,14 +43,7 @@ | |||||||
| #include "inet_net_pton.h" | #include "inet_net_pton.h" | ||||||
| #include "ares_getopt.h" | #include "ares_getopt.h" | ||||||
|  |  | ||||||
| #ifndef HAVE_STRUCT_IN6_ADDR | static void callback(void *arg, int status, int timeouts, struct hostent *host); | ||||||
| struct in6_addr |  | ||||||
| { |  | ||||||
|   unsigned char s6_addr[16]; |  | ||||||
| }; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| static void callback(void *arg, int status, struct hostent *host); |  | ||||||
| static void usage(void); | static void usage(void); | ||||||
|  |  | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| @@ -142,10 +138,12 @@ int main(int argc, char **argv) | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void callback(void *arg, int status, struct hostent *host) | static void callback(void *arg, int status, int timeouts, struct hostent *host) | ||||||
| { | { | ||||||
|   char **p; |   char **p; | ||||||
|  |  | ||||||
|  |   (void)timeouts; | ||||||
|  |  | ||||||
|   if (status != ARES_SUCCESS) |   if (status != ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status)); |       fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status)); | ||||||
|   | |||||||
							
								
								
									
										73
									
								
								ares/ares.h
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								ares/ares.h
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | |||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  |  * Copyright (C) 2007 by Daniel Stenberg | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
| @@ -18,6 +19,14 @@ | |||||||
| #ifndef ARES__H | #ifndef ARES__H | ||||||
| #define ARES__H | #define ARES__H | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Define WIN32 when build target is Win32 API | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) | ||||||
|  | #define WIN32 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
|  |  | ||||||
| #if defined(_AIX) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) | #if defined(_AIX) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) | ||||||
| @@ -35,8 +44,12 @@ | |||||||
|   #include <sys/socket.h> |   #include <sys/socket.h> | ||||||
|   #include <tcp.h> |   #include <tcp.h> | ||||||
| #elif defined(WIN32) | #elif defined(WIN32) | ||||||
|   #include <winsock2.h> | #  ifndef WIN32_LEAN_AND_MEAN | ||||||
|   #include <windows.h> | #    define WIN32_LEAN_AND_MEAN | ||||||
|  | #  endif | ||||||
|  | #  include <windows.h> | ||||||
|  | #  include <winsock2.h> | ||||||
|  | #  include <ws2tcpip.h> | ||||||
| #else | #else | ||||||
|   #include <netinet/in.h> |   #include <netinet/in.h> | ||||||
|   #include <sys/socket.h> |   #include <sys/socket.h> | ||||||
| @@ -98,6 +111,9 @@ extern "C" { | |||||||
| #define ARES_OPT_LOOKUPS        (1 << 8) | #define ARES_OPT_LOOKUPS        (1 << 8) | ||||||
| #define ARES_OPT_SOCK_STATE_CB  (1 << 9) | #define ARES_OPT_SOCK_STATE_CB  (1 << 9) | ||||||
| #define ARES_OPT_SORTLIST       (1 << 10) | #define ARES_OPT_SORTLIST       (1 << 10) | ||||||
|  | #define ARES_OPT_SOCK_SNDBUF    (1 << 11) | ||||||
|  | #define ARES_OPT_SOCK_RCVBUF    (1 << 12) | ||||||
|  | #define ARES_OPT_TIMEOUTMS      (1 << 13) | ||||||
|  |  | ||||||
| /* Nameinfo flag values */ | /* Nameinfo flag values */ | ||||||
| #define ARES_NI_NOFQDN                  (1 << 0) | #define ARES_NI_NOFQDN                  (1 << 0) | ||||||
| @@ -156,27 +172,22 @@ typedef int ares_socket_t; | |||||||
| #define ares_socket_typedef | #define ares_socket_typedef | ||||||
| #endif /* ares_socket_typedef */ | #endif /* ares_socket_typedef */ | ||||||
|  |  | ||||||
| #ifdef WIN32 |  | ||||||
| typedef void (*ares_sock_state_cb)(void *data, | typedef void (*ares_sock_state_cb)(void *data, | ||||||
|                                    SOCKET socket, |                                    ares_socket_t socket_fd, | ||||||
|                                    int readable, |                                    int readable, | ||||||
|                                    int writable); |                                    int writable); | ||||||
| #else |  | ||||||
| typedef void (*ares_sock_state_cb)(void *data, |  | ||||||
|                                    int socket, |  | ||||||
|                                    int readable, |  | ||||||
|                                    int writable); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| struct apattern; | struct apattern; | ||||||
|  |  | ||||||
| struct ares_options { | struct ares_options { | ||||||
|   int flags; |   int flags; | ||||||
|   int timeout; |   int timeout; /* in seconds or milliseconds, depending on options */ | ||||||
|   int tries; |   int tries; | ||||||
|   int ndots; |   int ndots; | ||||||
|   unsigned short udp_port; |   unsigned short udp_port; | ||||||
|   unsigned short tcp_port; |   unsigned short tcp_port; | ||||||
|  |   int socket_send_buffer_size; | ||||||
|  |   int socket_receive_buffer_size; | ||||||
|   struct in_addr *servers; |   struct in_addr *servers; | ||||||
|   int nservers; |   int nservers; | ||||||
|   char **domains; |   char **domains; | ||||||
| @@ -193,11 +204,11 @@ struct timeval; | |||||||
| struct sockaddr; | struct sockaddr; | ||||||
| struct ares_channeldata; | struct ares_channeldata; | ||||||
| typedef struct ares_channeldata *ares_channel; | typedef struct ares_channeldata *ares_channel; | ||||||
| typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf, | typedef void (*ares_callback)(void *arg, int status, int timeouts, | ||||||
|                               int alen); |                               unsigned char *abuf, int alen); | ||||||
| typedef void (*ares_host_callback)(void *arg, int status, | typedef void (*ares_host_callback)(void *arg, int status, int timeouts, | ||||||
|                                    struct hostent *hostent); |                                    struct hostent *hostent); | ||||||
| typedef void (*ares_nameinfo_callback)(void *arg, int status, | typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts, | ||||||
|                                        char *node, char *service); |                                        char *node, char *service); | ||||||
|  |  | ||||||
| int ares_init(ares_channel *channelptr); | int ares_init(ares_channel *channelptr); | ||||||
| @@ -235,10 +246,38 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, | |||||||
|                      int alen, char **s, long *enclen); |                      int alen, char **s, long *enclen); | ||||||
| int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, | int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, | ||||||
|                      int alen, unsigned char **s, long *enclen); |                      int alen, unsigned char **s, long *enclen); | ||||||
|  |  | ||||||
|  | #if !defined(HAVE_STRUCT_IN6_ADDR) && !defined(s6_addr) | ||||||
|  | struct in6_addr { | ||||||
|  |   union { | ||||||
|  |     unsigned char _S6_u8[16]; | ||||||
|  |   } _S6_un; | ||||||
|  | }; | ||||||
|  | #define s6_addr _S6_un._S6_u8 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct addrttl { | ||||||
|  |   struct in_addr ipaddr; | ||||||
|  |   int            ttl; | ||||||
|  | }; | ||||||
|  | struct addr6ttl { | ||||||
|  |   struct in6_addr ip6addr; | ||||||
|  |   int             ttl; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** Parse the buffer, starting at *abuf and of length alen bytes, previously | ||||||
|  | ** obtained from an ares_search call.  Put the results in *host, if nonnull. | ||||||
|  | ** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with | ||||||
|  | ** their TTLs in that array, and set *naddrttls to the number of addresses | ||||||
|  | ** so written. | ||||||
|  | */ | ||||||
| int ares_parse_a_reply(const unsigned char *abuf, int alen, | int ares_parse_a_reply(const unsigned char *abuf, int alen, | ||||||
|                        struct hostent **host); |                        struct hostent **host, | ||||||
|  |                        struct addrttl *addrttls, int *naddrttls); | ||||||
| int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | ||||||
|                        struct hostent **host); |                        struct hostent **host, | ||||||
|  |                        struct addr6ttl *addrttls, int *naddrttls); | ||||||
| int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | ||||||
|                          int addrlen, int family, struct hostent **host); |                          int addrlen, int family, struct hostent **host); | ||||||
| int ares_parse_ns_reply(const unsigned char *abuf, int alen, | int ares_parse_ns_reply(const unsigned char *abuf, int alen, | ||||||
|   | |||||||
| @@ -35,6 +35,8 @@ void ares__close_sockets(ares_channel channel, struct server_state *server) | |||||||
|       /* Advance server->qhead; pull out query as we go. */ |       /* Advance server->qhead; pull out query as we go. */ | ||||||
|       sendreq = server->qhead; |       sendreq = server->qhead; | ||||||
|       server->qhead = sendreq->next; |       server->qhead = sendreq->next; | ||||||
|  |       if (sendreq->data_storage != NULL) | ||||||
|  |         free(sendreq->data_storage); | ||||||
|       free(sendreq); |       free(sendreq); | ||||||
|     } |     } | ||||||
|   server->qtail = NULL; |   server->qtail = NULL; | ||||||
| @@ -45,12 +47,16 @@ void ares__close_sockets(ares_channel channel, struct server_state *server) | |||||||
|   server->tcp_buffer = NULL; |   server->tcp_buffer = NULL; | ||||||
|   server->tcp_lenbuf_pos = 0; |   server->tcp_lenbuf_pos = 0; | ||||||
|  |  | ||||||
|  |   /* Reset brokenness */ | ||||||
|  |   server->is_broken = 0; | ||||||
|  |  | ||||||
|   /* Close the TCP and UDP sockets. */ |   /* Close the TCP and UDP sockets. */ | ||||||
|   if (server->tcp_socket != ARES_SOCKET_BAD) |   if (server->tcp_socket != ARES_SOCKET_BAD) | ||||||
|     { |     { | ||||||
|       SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0); |       SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0); | ||||||
|       closesocket(server->tcp_socket); |       closesocket(server->tcp_socket); | ||||||
|       server->tcp_socket = ARES_SOCKET_BAD; |       server->tcp_socket = ARES_SOCKET_BAD; | ||||||
|  |       server->tcp_connection_generation = ++channel->tcp_connection_generation; | ||||||
|     } |     } | ||||||
|   if (server->udp_socket != ARES_SOCKET_BAD) |   if (server->udp_socket != ARES_SOCKET_BAD) | ||||||
|     { |     { | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								ares/ares__timeval.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								ares/ares__timeval.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | /* $Id$ */ | ||||||
|  |  | ||||||
|  | /* Copyright (C) 2008 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "setup.h" | ||||||
|  | #include "ares.h" | ||||||
|  | #include "ares_private.h" | ||||||
|  |  | ||||||
|  | #if defined(WIN32) && !defined(MSDOS) | ||||||
|  |  | ||||||
|  | struct timeval ares__tvnow(void) | ||||||
|  | { | ||||||
|  |   /* | ||||||
|  |   ** GetTickCount() is available on _all_ Windows versions from W95 up | ||||||
|  |   ** to nowadays. Returns milliseconds elapsed since last system boot, | ||||||
|  |   ** increases monotonically and wraps once 49.7 days have elapsed. | ||||||
|  |   */ | ||||||
|  |   struct timeval now; | ||||||
|  |   DWORD milliseconds = GetTickCount(); | ||||||
|  |   now.tv_sec = milliseconds / 1000; | ||||||
|  |   now.tv_usec = (milliseconds % 1000) * 1000; | ||||||
|  |   return now; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) | ||||||
|  |  | ||||||
|  | struct timeval ares__tvnow(void) | ||||||
|  | { | ||||||
|  |   /* | ||||||
|  |   ** clock_gettime() is granted to be increased monotonically when the | ||||||
|  |   ** monotonic clock is queried. Time starting point is unspecified, it | ||||||
|  |   ** could be the system start-up time, the Epoch, or something else, | ||||||
|  |   ** in any case the time starting point does not change once that the | ||||||
|  |   ** system has started up. | ||||||
|  |   */ | ||||||
|  |   struct timeval now; | ||||||
|  |   struct timespec tsnow; | ||||||
|  |   if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { | ||||||
|  |     now.tv_sec = tsnow.tv_sec; | ||||||
|  |     now.tv_usec = tsnow.tv_nsec / 1000; | ||||||
|  |   } | ||||||
|  |   /* | ||||||
|  |   ** Even when the configure process has truly detected monotonic clock | ||||||
|  |   ** availability, it might happen that it is not actually available at | ||||||
|  |   ** run-time. When this occurs simply fallback to other time source. | ||||||
|  |   */ | ||||||
|  | #ifdef HAVE_GETTIMEOFDAY | ||||||
|  |   else | ||||||
|  |     (void)gettimeofday(&now, NULL); | ||||||
|  | #else | ||||||
|  |   else { | ||||||
|  |     now.tv_sec = (long)time(NULL); | ||||||
|  |     now.tv_usec = 0; | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   return now; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #elif defined(HAVE_GETTIMEOFDAY) | ||||||
|  |  | ||||||
|  | struct timeval ares__tvnow(void) | ||||||
|  | { | ||||||
|  |   /* | ||||||
|  |   ** gettimeofday() is not granted to be increased monotonically, due to | ||||||
|  |   ** clock drifting and external source time synchronization it can jump | ||||||
|  |   ** forward or backward in time. | ||||||
|  |   */ | ||||||
|  |   struct timeval now; | ||||||
|  |   (void)gettimeofday(&now, NULL); | ||||||
|  |   return now; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | struct timeval ares__tvnow(void) | ||||||
|  | { | ||||||
|  |   /* | ||||||
|  |   ** time() returns the value of time in seconds since the Epoch. | ||||||
|  |   */ | ||||||
|  |   struct timeval now; | ||||||
|  |   now.tv_sec = (long)time(NULL); | ||||||
|  |   now.tv_usec = 0; | ||||||
|  |   return now; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if 0 /* Not used */ | ||||||
|  | /* | ||||||
|  |  * Make sure that the first argument is the more recent time, as otherwise | ||||||
|  |  * we'll get a weird negative time-diff back... | ||||||
|  |  * | ||||||
|  |  * Returns: the time difference in number of milliseconds. | ||||||
|  |  */ | ||||||
|  | long ares__tvdiff(struct timeval newer, struct timeval older) | ||||||
|  | { | ||||||
|  |   return (newer.tv_sec-older.tv_sec)*1000+ | ||||||
|  |     (newer.tv_usec-older.tv_usec)/1000; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| @@ -14,29 +14,45 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "setup.h" | #include "setup.h" | ||||||
|  | #include <assert.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include "ares.h" | #include "ares.h" | ||||||
| #include "ares_private.h" | #include "ares_private.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * ares_cancel() cancels a ongoing request/resolve that might be going on on |  * ares_cancel() cancels all ongoing requests/resolves that might be going on | ||||||
|  * the given channel. It does NOT kill the channel, use ares_destroy() for |  * on the given channel. It does NOT kill the channel, use ares_destroy() for | ||||||
|  * that. |  * that. | ||||||
|  */ |  */ | ||||||
| void ares_cancel(ares_channel channel) | void ares_cancel(ares_channel channel) | ||||||
| { | { | ||||||
|   struct query *query, *next; |   struct query *query; | ||||||
|  |   struct list_node* list_head; | ||||||
|  |   struct list_node* list_node; | ||||||
|   int i; |   int i; | ||||||
|  |  | ||||||
|   for (query = channel->queries; query; query = next) |   list_head = &(channel->all_queries); | ||||||
|  |   for (list_node = list_head->next; list_node != list_head; ) | ||||||
|   { |   { | ||||||
|     next = query->next; |     query = list_node->data; | ||||||
|     query->callback(query->arg, ARES_ETIMEOUT, NULL, 0); |     list_node = list_node->next;  /* since we're deleting the query */ | ||||||
|     free(query->tcpbuf); |     query->callback(query->arg, ARES_ETIMEOUT, 0, NULL, 0); | ||||||
|     free(query->skip_server); |     ares__free_query(query); | ||||||
|     free(query); |  | ||||||
|   } |   } | ||||||
|   channel->queries = NULL; | #ifndef NDEBUG | ||||||
|  |   /* Freeing the query should remove it from all the lists in which it sits, | ||||||
|  |    * so all query lists should be empty now. | ||||||
|  |    */ | ||||||
|  |   assert(ares__is_list_empty(&(channel->all_queries))); | ||||||
|  |   for (i = 0; i < ARES_QID_TABLE_SIZE; i++) | ||||||
|  |     { | ||||||
|  |       assert(ares__is_list_empty(&(channel->queries_by_qid[i]))); | ||||||
|  |     } | ||||||
|  |   for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) | ||||||
|  |     { | ||||||
|  |       assert(ares__is_list_empty(&(channel->queries_by_timeout[i]))); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|   if (!(channel->flags & ARES_FLAG_STAYOPEN)) |   if (!(channel->flags & ARES_FLAG_STAYOPEN)) | ||||||
|   { |   { | ||||||
|     if (channel->servers) |     if (channel->servers) | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "setup.h" | #include "setup.h" | ||||||
|  | #include <assert.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include "ares.h" | #include "ares.h" | ||||||
| #include "ares_private.h" | #include "ares_private.h" | ||||||
| @@ -37,13 +38,42 @@ void ares_destroy(ares_channel channel) | |||||||
| { | { | ||||||
|   int i; |   int i; | ||||||
|   struct query *query; |   struct query *query; | ||||||
|  |   struct list_node* list_head; | ||||||
|  |   struct list_node* list_node; | ||||||
|    |    | ||||||
|   if (!channel) |   if (!channel) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|  |   list_head = &(channel->all_queries); | ||||||
|  |   for (list_node = list_head->next; list_node != list_head; ) | ||||||
|  |     { | ||||||
|  |       query = list_node->data; | ||||||
|  |       list_node = list_node->next;  /* since we're deleting the query */ | ||||||
|  |       query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0); | ||||||
|  |       ares__free_query(query); | ||||||
|  |     } | ||||||
|  | #ifndef NDEBUG | ||||||
|  |   /* Freeing the query should remove it from all the lists in which it sits, | ||||||
|  |    * so all query lists should be empty now. | ||||||
|  |    */ | ||||||
|  |   assert(ares__is_list_empty(&(channel->all_queries))); | ||||||
|  |   for (i = 0; i < ARES_QID_TABLE_SIZE; i++) | ||||||
|  |     { | ||||||
|  |       assert(ares__is_list_empty(&(channel->queries_by_qid[i]))); | ||||||
|  |     } | ||||||
|  |   for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) | ||||||
|  |     { | ||||||
|  |       assert(ares__is_list_empty(&(channel->queries_by_timeout[i]))); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   if (channel->servers) { |   if (channel->servers) { | ||||||
|     for (i = 0; i < channel->nservers; i++) |     for (i = 0; i < channel->nservers; i++) | ||||||
|       ares__close_sockets(channel, &channel->servers[i]); |       { | ||||||
|  |         struct server_state *server = &channel->servers[i]; | ||||||
|  |         ares__close_sockets(channel, server); | ||||||
|  |         assert(ares__is_list_empty(&(server->queries_to_server))); | ||||||
|  |       } | ||||||
|     free(channel->servers); |     free(channel->servers); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -59,16 +89,5 @@ void ares_destroy(ares_channel channel) | |||||||
|   if (channel->lookups) |   if (channel->lookups) | ||||||
|     free(channel->lookups); |     free(channel->lookups); | ||||||
|  |  | ||||||
|   while (channel->queries) { |  | ||||||
|     query = channel->queries; |  | ||||||
|     channel->queries = query->next; |  | ||||||
|     query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0); |  | ||||||
|     if (query->tcpbuf) |  | ||||||
|       free(query->tcpbuf); |  | ||||||
|     if (query->skip_server) |  | ||||||
|       free(query->skip_server); |  | ||||||
|     free(query); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   free(channel); |   free(channel); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -74,6 +74,15 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, | |||||||
|     return ARES_ENOMEM; |     return ARES_ENOMEM; | ||||||
|   q = *s; |   q = *s; | ||||||
|  |  | ||||||
|  |   if (len == 0) { | ||||||
|  |     /* RFC2181 says this should be ".": the root of the DNS tree. | ||||||
|  |      * Since this function strips trailing dots though, it becomes "" | ||||||
|  |      */ | ||||||
|  |     q[0] = '\0'; | ||||||
|  |     *enclen = 1;  /* the caller should move one byte to get past this */ | ||||||
|  |     return ARES_SUCCESS; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* No error-checking necessary; it was all done by name_length(). */ |   /* No error-checking necessary; it was all done by name_length(). */ | ||||||
|   p = encoded; |   p = encoded; | ||||||
|   while (*p) |   while (*p) | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ ares_expand_string \- Expand a length encoded string | |||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| The | The | ||||||
| .B ares_expand_string | .B ares_expand_string | ||||||
| function converts a length encoded string to a NULL terminated C | function converts a length encoded string to a NUL-terminated C | ||||||
| string.  The argument | string.  The argument | ||||||
| .I encoded | .I encoded | ||||||
| gives the beginning of the encoded string, and the arguments | gives the beginning of the encoded string, and the arguments | ||||||
|   | |||||||
| @@ -30,20 +30,26 @@ int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds) | |||||||
|   ares_socket_t nfds; |   ares_socket_t nfds; | ||||||
|   int i; |   int i; | ||||||
|  |  | ||||||
|   /* No queries, no file descriptors. */ |   /* Are there any active queries? */ | ||||||
|   if (!channel->queries) |   int active_queries = !ares__is_list_empty(&(channel->all_queries)); | ||||||
|     return 0; |  | ||||||
|  |  | ||||||
|   nfds = 0; |   nfds = 0; | ||||||
|   for (i = 0; i < channel->nservers; i++) |   for (i = 0; i < channel->nservers; i++) | ||||||
|     { |     { | ||||||
|       server = &channel->servers[i]; |       server = &channel->servers[i]; | ||||||
|       if (server->udp_socket != ARES_SOCKET_BAD) |       /* We only need to register interest in UDP sockets if we have | ||||||
|  |        * outstanding queries. | ||||||
|  |        */ | ||||||
|  |       if (active_queries && server->udp_socket != ARES_SOCKET_BAD) | ||||||
|         { |         { | ||||||
|           FD_SET(server->udp_socket, read_fds); |           FD_SET(server->udp_socket, read_fds); | ||||||
|           if (server->udp_socket >= nfds) |           if (server->udp_socket >= nfds) | ||||||
|             nfds = server->udp_socket + 1; |             nfds = server->udp_socket + 1; | ||||||
|         } |         } | ||||||
|  |       /* We always register for TCP events, because we want to know | ||||||
|  |        * when the other side closes the connection, so we don't waste | ||||||
|  |        * time trying to use a broken connection. | ||||||
|  |        */ | ||||||
|       if (server->tcp_socket != ARES_SOCKET_BAD) |       if (server->tcp_socket != ARES_SOCKET_BAD) | ||||||
|        { |        { | ||||||
|          FD_SET(server->tcp_socket, read_fds); |          FD_SET(server->tcp_socket, read_fds); | ||||||
|   | |||||||
| @@ -33,12 +33,13 @@ allocated by one of the functions \fIares_parse_a_reply(3)\fP, | |||||||
| .SH NOTES | .SH NOTES | ||||||
| It is not necessary (and is not correct) to free the host structure passed to | It is not necessary (and is not correct) to free the host structure passed to | ||||||
| the callback functions for \fIares_gethostbyname(3)\fP or | the callback functions for \fIares_gethostbyname(3)\fP or | ||||||
| \fIares_gethostbyaddr(3)\fP. The ares library will automatically free such | \fIares_gethostbyaddr(3)\fP. c-ares will automatically free such host | ||||||
| host structures when the callback returns. | structures when the callback returns. | ||||||
| .SH SEE ALSO | .SH SEE ALSO | ||||||
| .BR ares_parse_a_reply (3), | .BR ares_parse_a_reply (3), | ||||||
| .BR ares_parse_aaaa_reply (3), | .BR ares_parse_aaaa_reply (3), | ||||||
| .BR ares_parse_ptr_reply (3) | .BR ares_parse_ptr_reply (3), | ||||||
|  | .BR ares_parse_ns_reply (3) | ||||||
| .SH AUTHOR | .SH AUTHOR | ||||||
| Greg Hudson, MIT Information Systems | Greg Hudson, MIT Information Systems | ||||||
| .br | .br | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ ares_gethostbyaddr \- Initiate a host query by address | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, | .B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, | ||||||
| .B	struct hostent *\fIhostent\fP) | .B	int \fItimeouts\fP, struct hostent *\fIhostent\fP) | ||||||
| .PP | .PP | ||||||
| .B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP, | .B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP, | ||||||
| .B 	int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP, | .B 	int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP, | ||||||
| @@ -76,6 +76,11 @@ The name service channel | |||||||
| .I channel | .I channel | ||||||
| is being destroyed; the query will not be completed. | is being destroyed; the query will not be completed. | ||||||
| .PP | .PP | ||||||
|  | The callback argument | ||||||
|  | .I timeouts | ||||||
|  | reports how many times a query timed out during the execution of the | ||||||
|  | given request. | ||||||
|  | .PP | ||||||
| On successful completion of the query, the callback argument | On successful completion of the query, the callback argument | ||||||
| .I hostent | .I hostent | ||||||
| points to a | points to a | ||||||
|   | |||||||
| @@ -49,14 +49,16 @@ struct addr_query { | |||||||
|   void *arg; |   void *arg; | ||||||
|  |  | ||||||
|   const char *remaining_lookups; |   const char *remaining_lookups; | ||||||
|  |   int timeouts; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void next_lookup(struct addr_query *aquery); | static void next_lookup(struct addr_query *aquery); | ||||||
| static void addr_callback(void *arg, int status, unsigned char *abuf, | static void addr_callback(void *arg, int status, int timeouts, | ||||||
|                           int alen); |                           unsigned char *abuf, int alen); | ||||||
| static void end_aquery(struct addr_query *aquery, int status, | static void end_aquery(struct addr_query *aquery, int status, | ||||||
|                        struct hostent *host); |                        struct hostent *host); | ||||||
| static int file_lookup(union ares_addr *addr, int family, struct hostent **host); | static int file_lookup(union ares_addr *addr, int family, struct hostent **host); | ||||||
|  | static void ptr_rr_name(char *name, int family, union ares_addr *addr); | ||||||
|  |  | ||||||
| void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, | void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, | ||||||
|                         int family, ares_host_callback callback, void *arg) |                         int family, ares_host_callback callback, void *arg) | ||||||
| @@ -65,21 +67,21 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, | |||||||
|  |  | ||||||
|   if (family != AF_INET && family != AF_INET6) |   if (family != AF_INET && family != AF_INET6) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOTIMP, NULL); |       callback(arg, ARES_ENOTIMP, 0, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if ((family == AF_INET && addrlen != sizeof(struct in_addr)) || |   if ((family == AF_INET && addrlen != sizeof(struct in_addr)) || | ||||||
|       (family == AF_INET6 && addrlen != sizeof(struct in6_addr))) |       (family == AF_INET6 && addrlen != sizeof(struct in6_addr))) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOTIMP, NULL); |       callback(arg, ARES_ENOTIMP, 0, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   aquery = malloc(sizeof(struct addr_query)); |   aquery = malloc(sizeof(struct addr_query)); | ||||||
|   if (!aquery) |   if (!aquery) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOMEM, NULL); |       callback(arg, ARES_ENOMEM, 0, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   aquery->channel = channel; |   aquery->channel = channel; | ||||||
| @@ -91,6 +93,7 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, | |||||||
|   aquery->callback = callback; |   aquery->callback = callback; | ||||||
|   aquery->arg = arg; |   aquery->arg = arg; | ||||||
|   aquery->remaining_lookups = channel->lookups; |   aquery->remaining_lookups = channel->lookups; | ||||||
|  |   aquery->timeouts = 0; | ||||||
|  |  | ||||||
|   next_lookup(aquery); |   next_lookup(aquery); | ||||||
| } | } | ||||||
| @@ -99,48 +102,26 @@ static void next_lookup(struct addr_query *aquery) | |||||||
| { | { | ||||||
|   const char *p; |   const char *p; | ||||||
|   char name[128]; |   char name[128]; | ||||||
|   int a1, a2, a3, a4, status; |   int status; | ||||||
|   struct hostent *host; |   struct hostent *host; | ||||||
|   unsigned long addr; |  | ||||||
|  |  | ||||||
|   for (p = aquery->remaining_lookups; *p; p++) |   for (p = aquery->remaining_lookups; *p; p++) | ||||||
|     { |     { | ||||||
|       switch (*p) |       switch (*p) | ||||||
|         { |         { | ||||||
|         case 'b': |         case 'b': | ||||||
|           if (aquery->family == AF_INET) |           ptr_rr_name(name, aquery->family, &aquery->addr); | ||||||
|             { |  | ||||||
|               addr = ntohl(aquery->addr.addr4.s_addr); |  | ||||||
|               a1 = (int)((addr >> 24) & 0xff); |  | ||||||
|               a2 = (int)((addr >> 16) & 0xff); |  | ||||||
|               a3 = (int)((addr >> 8) & 0xff); |  | ||||||
|               a4 = (int)(addr & 0xff); |  | ||||||
|               sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1); |  | ||||||
|           aquery->remaining_lookups = p + 1; |           aquery->remaining_lookups = p + 1; | ||||||
|           ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, |           ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, | ||||||
|                      aquery); |                      aquery); | ||||||
|             } |  | ||||||
|           else |  | ||||||
|             { |  | ||||||
|               unsigned char *bytes; |  | ||||||
|               bytes = (unsigned char *)&aquery->addr.addr6.s6_addr; |  | ||||||
|               sprintf(name, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa", |  | ||||||
|                       bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4, |  | ||||||
|                       bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4, |  | ||||||
|                       bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4, |  | ||||||
|                       bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4, |  | ||||||
|                       bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4, |  | ||||||
|                       bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4, |  | ||||||
|                       bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4, |  | ||||||
|                       bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4); |  | ||||||
|               aquery->remaining_lookups = p + 1; |  | ||||||
|               ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, |  | ||||||
|                          aquery); |  | ||||||
|             } |  | ||||||
|           return; |           return; | ||||||
|         case 'f': |         case 'f': | ||||||
|           status = file_lookup(&aquery->addr, aquery->family, &host); |           status = file_lookup(&aquery->addr, aquery->family, &host); | ||||||
|           if (status != ARES_ENOTFOUND) |  | ||||||
|  |           /* this status check below previously checked for !ARES_ENOTFOUND, | ||||||
|  |              but we should not assume that this single error code is the one | ||||||
|  |              that can occur, as that is in fact no longer the case */ | ||||||
|  |           if (status == ARES_SUCCESS) | ||||||
|             { |             { | ||||||
|               end_aquery(aquery, status, host); |               end_aquery(aquery, status, host); | ||||||
|               return; |               return; | ||||||
| @@ -151,11 +132,13 @@ static void next_lookup(struct addr_query *aquery) | |||||||
|   end_aquery(aquery, ARES_ENOTFOUND, NULL); |   end_aquery(aquery, ARES_ENOTFOUND, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void addr_callback(void *arg, int status, unsigned char *abuf, int alen) | static void addr_callback(void *arg, int status, int timeouts, | ||||||
|  |                           unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   struct addr_query *aquery = (struct addr_query *) arg; |   struct addr_query *aquery = (struct addr_query *) arg; | ||||||
|   struct hostent *host; |   struct hostent *host; | ||||||
|  |  | ||||||
|  |   aquery->timeouts += timeouts; | ||||||
|   if (status == ARES_SUCCESS) |   if (status == ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       if (aquery->family == AF_INET) |       if (aquery->family == AF_INET) | ||||||
| @@ -175,7 +158,7 @@ static void addr_callback(void *arg, int status, unsigned char *abuf, int alen) | |||||||
| static void end_aquery(struct addr_query *aquery, int status, | static void end_aquery(struct addr_query *aquery, int status, | ||||||
|                        struct hostent *host) |                        struct hostent *host) | ||||||
| { | { | ||||||
|   aquery->callback(aquery->arg, status, host); |   aquery->callback(aquery->arg, status, aquery->timeouts, host); | ||||||
|   if (host) |   if (host) | ||||||
|     ares_free_hostent(host); |     ares_free_hostent(host); | ||||||
|   free(aquery); |   free(aquery); | ||||||
| @@ -260,3 +243,31 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host) | |||||||
|     *host = NULL; |     *host = NULL; | ||||||
|   return status; |   return status; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void ptr_rr_name(char *name, int family, union ares_addr *addr) | ||||||
|  | { | ||||||
|  |   if (family == AF_INET) | ||||||
|  |     { | ||||||
|  |        unsigned long laddr = ntohl(addr->addr4.s_addr); | ||||||
|  |        int a1 = (int)((laddr >> 24) & 0xff); | ||||||
|  |        int a2 = (int)((laddr >> 16) & 0xff); | ||||||
|  |        int a3 = (int)((laddr >> 8) & 0xff); | ||||||
|  |        int a4 = (int)(laddr & 0xff); | ||||||
|  |        sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |        unsigned char *bytes = (unsigned char *)&addr->addr6.s6_addr; | ||||||
|  |        sprintf(name, | ||||||
|  |                 "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x." | ||||||
|  |                 "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa", | ||||||
|  |                 bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4, | ||||||
|  |                 bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4, | ||||||
|  |                 bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4, | ||||||
|  |                 bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4, | ||||||
|  |                 bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4, | ||||||
|  |                 bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4, | ||||||
|  |                 bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4, | ||||||
|  |                 bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4); | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ ares_gethostbyname \- Initiate a host query by name | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, | .B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, | ||||||
| .B	struct hostent *\fIhostent\fP) | .B	int \fItimeouts\fP, struct hostent *\fIhostent\fP) | ||||||
| .PP | .PP | ||||||
| .B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP, | .B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP, | ||||||
| .B 	int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP) | .B 	int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP) | ||||||
| @@ -80,6 +80,11 @@ The name service channel | |||||||
| .I channel | .I channel | ||||||
| is being destroyed; the query will not be completed. | is being destroyed; the query will not be completed. | ||||||
| .PP | .PP | ||||||
|  | The callback argument | ||||||
|  | .I timeouts | ||||||
|  | reports how many times a query timed out during the execution of the | ||||||
|  | given request. | ||||||
|  | .PP | ||||||
| On successful completion of the query, the callback argument | On successful completion of the query, the callback argument | ||||||
| .I hostent | .I hostent | ||||||
| points to a | points to a | ||||||
|   | |||||||
| @@ -36,6 +36,9 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include "ares.h" | #include "ares.h" | ||||||
| #include "ares_private.h" | #include "ares_private.h" | ||||||
| @@ -54,11 +57,12 @@ struct host_query { | |||||||
|   void *arg; |   void *arg; | ||||||
|   int family; |   int family; | ||||||
|   const char *remaining_lookups; |   const char *remaining_lookups; | ||||||
|  |   int timeouts; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void next_lookup(struct host_query *hquery); | static void next_lookup(struct host_query *hquery, int status_code); | ||||||
| static void host_callback(void *arg, int status, unsigned char *abuf, | static void host_callback(void *arg, int status, int timeouts, | ||||||
|                           int alen); |                           unsigned char *abuf, int alen); | ||||||
| static void end_hquery(struct host_query *hquery, int status, | static void end_hquery(struct host_query *hquery, int status, | ||||||
|                        struct hostent *host); |                        struct hostent *host); | ||||||
| static int fake_hostent(const char *name, int family, ares_host_callback callback, | static int fake_hostent(const char *name, int family, ares_host_callback callback, | ||||||
| @@ -81,7 +85,7 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, | |||||||
|   /* Right now we only know how to look up Internet addresses. */ |   /* Right now we only know how to look up Internet addresses. */ | ||||||
|   if (family != AF_INET && family != AF_INET6) |   if (family != AF_INET && family != AF_INET6) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOTIMP, NULL); |       callback(arg, ARES_ENOTIMP, 0, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -92,7 +96,7 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, | |||||||
|   hquery = malloc(sizeof(struct host_query)); |   hquery = malloc(sizeof(struct host_query)); | ||||||
|   if (!hquery) |   if (!hquery) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOMEM, NULL); |       callback(arg, ARES_ENOMEM, 0, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   hquery->channel = channel; |   hquery->channel = channel; | ||||||
| @@ -101,22 +105,23 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, | |||||||
|   if (!hquery->name) |   if (!hquery->name) | ||||||
|     { |     { | ||||||
|       free(hquery); |       free(hquery); | ||||||
|       callback(arg, ARES_ENOMEM, NULL); |       callback(arg, ARES_ENOMEM, 0, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   hquery->callback = callback; |   hquery->callback = callback; | ||||||
|   hquery->arg = arg; |   hquery->arg = arg; | ||||||
|   hquery->remaining_lookups = channel->lookups; |   hquery->remaining_lookups = channel->lookups; | ||||||
|  |   hquery->timeouts = 0; | ||||||
|  |  | ||||||
|   /* Start performing lookups according to channel->lookups. */ |   /* Start performing lookups according to channel->lookups. */ | ||||||
|   next_lookup(hquery); |   next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void next_lookup(struct host_query *hquery) | static void next_lookup(struct host_query *hquery, int status_code) | ||||||
| { | { | ||||||
|   int status; |  | ||||||
|   const char *p; |   const char *p; | ||||||
|   struct hostent *host; |   struct hostent *host; | ||||||
|  |   int status = status_code; | ||||||
|  |  | ||||||
|   for (p = hquery->remaining_lookups; *p; p++) |   for (p = hquery->remaining_lookups; *p; p++) | ||||||
|     { |     { | ||||||
| @@ -126,8 +131,8 @@ static void next_lookup(struct host_query *hquery) | |||||||
|           /* DNS lookup */ |           /* DNS lookup */ | ||||||
|           hquery->remaining_lookups = p + 1; |           hquery->remaining_lookups = p + 1; | ||||||
|           if (hquery->family == AF_INET6) |           if (hquery->family == AF_INET6) | ||||||
|             ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback, |             ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, | ||||||
|                         hquery); |                         host_callback, hquery); | ||||||
|           else |           else | ||||||
|             ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, |             ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, | ||||||
|                         hquery); |                         hquery); | ||||||
| @@ -136,34 +141,50 @@ static void next_lookup(struct host_query *hquery) | |||||||
|         case 'f': |         case 'f': | ||||||
|           /* Host file lookup */ |           /* Host file lookup */ | ||||||
|           status = file_lookup(hquery->name, hquery->family, &host); |           status = file_lookup(hquery->name, hquery->family, &host); | ||||||
|           if (status != ARES_ENOTFOUND) |  | ||||||
|  |           /* this status check below previously checked for !ARES_ENOTFOUND, | ||||||
|  |              but we should not assume that this single error code is the one | ||||||
|  |              that can occur, as that is in fact no longer the case */ | ||||||
|  |           if (status == ARES_SUCCESS) | ||||||
|             { |             { | ||||||
|               end_hquery(hquery, status, host); |               end_hquery(hquery, status, host); | ||||||
|               return; |               return; | ||||||
|             } |             } | ||||||
|  |           status = status_code;   /* Use original status code */ | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   end_hquery(hquery, ARES_ENOTFOUND, NULL); |   end_hquery(hquery, status, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void host_callback(void *arg, int status, unsigned char *abuf, int alen) | static void host_callback(void *arg, int status, int timeouts, | ||||||
|  |                           unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   struct host_query *hquery = (struct host_query *) arg; |   struct host_query *hquery = (struct host_query *) arg; | ||||||
|   ares_channel channel = hquery->channel; |   ares_channel channel = hquery->channel; | ||||||
|   struct hostent *host; |   struct hostent *host = NULL; | ||||||
|  |  | ||||||
|  |   hquery->timeouts += timeouts; | ||||||
|   if (status == ARES_SUCCESS) |   if (status == ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       if (hquery->family == AF_INET) |       if (hquery->family == AF_INET) | ||||||
|         { |         { | ||||||
|           status = ares_parse_a_reply(abuf, alen, &host); |           status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); | ||||||
|           if (host && channel->nsort) |           if (host && channel->nsort) | ||||||
|             sort_addresses(host, channel->sortlist, channel->nsort); |             sort_addresses(host, channel->sortlist, channel->nsort); | ||||||
|         } |         } | ||||||
|       else if (hquery->family == AF_INET6) |       else if (hquery->family == AF_INET6) | ||||||
|         { |         { | ||||||
|           status = ares_parse_aaaa_reply(abuf, alen, &host); |           status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); | ||||||
|  |           if (status == ARES_ENODATA) | ||||||
|  |             { | ||||||
|  |               /* The query returned something (e.g. CNAME) but there were no | ||||||
|  |                  AAAA records.  Try looking up A instead.  */ | ||||||
|  |               hquery->family = AF_INET; | ||||||
|  |               ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, | ||||||
|  |                           hquery); | ||||||
|  |               return; | ||||||
|  |             } | ||||||
|           if (host && channel->nsort) |           if (host && channel->nsort) | ||||||
|             sort6_addresses(host, channel->sortlist, channel->nsort); |             sort6_addresses(host, channel->sortlist, channel->nsort); | ||||||
|         } |         } | ||||||
| @@ -179,13 +200,13 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen) | |||||||
|   else if (status == ARES_EDESTRUCTION) |   else if (status == ARES_EDESTRUCTION) | ||||||
|     end_hquery(hquery, status, NULL); |     end_hquery(hquery, status, NULL); | ||||||
|   else |   else | ||||||
|     next_lookup(hquery); |     next_lookup(hquery, status); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void end_hquery(struct host_query *hquery, int status, | static void end_hquery(struct host_query *hquery, int status, | ||||||
|                        struct hostent *host) |                        struct hostent *host) | ||||||
| { | { | ||||||
|   hquery->callback(hquery->arg, status, host); |   hquery->callback(hquery->arg, status, hquery->timeouts, host); | ||||||
|   if (host) |   if (host) | ||||||
|     ares_free_hostent(host); |     ares_free_hostent(host); | ||||||
|   free(hquery->name); |   free(hquery->name); | ||||||
| @@ -206,7 +227,27 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac | |||||||
|   struct in6_addr in6; |   struct in6_addr in6; | ||||||
|  |  | ||||||
|   if (family == AF_INET) |   if (family == AF_INET) | ||||||
|  |     { | ||||||
|  |       /* It only looks like an IP address if it's all numbers and dots. */ | ||||||
|  |       int numdots = 0; | ||||||
|  |       const char *p; | ||||||
|  |       for (p = name; *p; p++) | ||||||
|  |         { | ||||||
|  |           if (!ISDIGIT(*p) && *p != '.') { | ||||||
|  |             return 0; | ||||||
|  |           } else if (*p == '.') { | ||||||
|  |             numdots++; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |       /* if we don't have 3 dots, it is illegal  | ||||||
|  |        * (although inet_addr doesn't think so). | ||||||
|  |        */ | ||||||
|  |       if (numdots != 3) | ||||||
|  |         result = 0; | ||||||
|  |       else | ||||||
|         result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1); |         result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1); | ||||||
|  |     } | ||||||
|   else if (family == AF_INET6) |   else if (family == AF_INET6) | ||||||
|     result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1); |     result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1); | ||||||
|  |  | ||||||
| @@ -227,7 +268,7 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac | |||||||
|   hostent.h_name = strdup(name); |   hostent.h_name = strdup(name); | ||||||
|   if (!hostent.h_name) |   if (!hostent.h_name) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOMEM, NULL); |       callback(arg, ARES_ENOMEM, 0, NULL); | ||||||
|       return 1; |       return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -236,7 +277,7 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac | |||||||
|   hostent.h_aliases = aliases; |   hostent.h_aliases = aliases; | ||||||
|   hostent.h_addrtype = family; |   hostent.h_addrtype = family; | ||||||
|   hostent.h_addr_list = addrs; |   hostent.h_addr_list = addrs; | ||||||
|   callback(arg, ARES_SUCCESS, &hostent); |   callback(arg, ARES_SUCCESS, 0, &hostent); | ||||||
|  |  | ||||||
|   free((char *)(hostent.h_name)); |   free((char *)(hostent.h_name)); | ||||||
|   return 1; |   return 1; | ||||||
| @@ -416,4 +457,3 @@ static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist, | |||||||
|     } |     } | ||||||
|   return i; |   return i; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ ares_getnameinfo \- Address-to-nodename translation in protocol-independent mann | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP, | .B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP, | ||||||
| .B	char *\fInode\fP, char *\fIservice\fP) | .B	int \fItimeouts\fP, char *\fInode\fP, char *\fIservice\fP) | ||||||
| .PP | .PP | ||||||
| .B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP, | .B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP, | ||||||
| .B 	socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP, | .B 	socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP, | ||||||
| @@ -120,6 +120,11 @@ The | |||||||
| .I flags | .I flags | ||||||
| parameter contains an illegal value. | parameter contains an illegal value. | ||||||
| .PP | .PP | ||||||
|  | The callback argument | ||||||
|  | .I timeouts | ||||||
|  | reports how many times a query timed out during the execution of the | ||||||
|  | given request. | ||||||
|  | .PP | ||||||
| On successful completion of the query, the callback argument | On successful completion of the query, the callback argument | ||||||
| .I node | .I node | ||||||
| contains a string representing the hostname (assuming  | contains a string representing the hostname (assuming  | ||||||
|   | |||||||
| @@ -59,6 +59,7 @@ struct nameinfo_query { | |||||||
|   } addr; |   } addr; | ||||||
|   int family; |   int family; | ||||||
|   int flags; |   int flags; | ||||||
|  |   int timeouts; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID | #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID | ||||||
| @@ -67,7 +68,7 @@ struct nameinfo_query { | |||||||
| #define IPBUFSIZ 40 | #define IPBUFSIZ 40 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| static void nameinfo_callback(void *arg, int status, struct hostent *host); | static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host); | ||||||
| static char *lookup_service(unsigned short port, int flags, | static char *lookup_service(unsigned short port, int flags, | ||||||
|                             char *buf, size_t buflen); |                             char *buf, size_t buflen); | ||||||
| #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID | #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID | ||||||
| @@ -90,7 +91,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t | |||||||
|     addr6 = (struct sockaddr_in6 *)sa; |     addr6 = (struct sockaddr_in6 *)sa; | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOTIMP, NULL, NULL); |       callback(arg, ARES_ENOTIMP, 0, NULL, NULL); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -110,7 +111,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t | |||||||
|         port = addr6->sin6_port; |         port = addr6->sin6_port; | ||||||
|       service = lookup_service((unsigned short)(port & 0xffff), |       service = lookup_service((unsigned short)(port & 0xffff), | ||||||
|                                flags, buf, sizeof(buf)); |                                flags, buf, sizeof(buf)); | ||||||
|       callback(arg, ARES_SUCCESS, NULL, service); |       callback(arg, ARES_SUCCESS, 0, NULL, service); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -131,7 +132,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t | |||||||
|          */ |          */ | ||||||
|         if (flags & ARES_NI_NAMEREQD) |         if (flags & ARES_NI_NAMEREQD) | ||||||
|           { |           { | ||||||
|             callback(arg, ARES_EBADFLAGS, NULL, NULL); |             callback(arg, ARES_EBADFLAGS, 0, NULL, NULL); | ||||||
|             return; |             return; | ||||||
|           } |           } | ||||||
|         if (salen == sizeof(struct sockaddr_in6)) |         if (salen == sizeof(struct sockaddr_in6)) | ||||||
| @@ -152,7 +153,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t | |||||||
|         if (flags & ARES_NI_LOOKUPSERVICE) |         if (flags & ARES_NI_LOOKUPSERVICE) | ||||||
|           service = lookup_service((unsigned short)(port & 0xffff), |           service = lookup_service((unsigned short)(port & 0xffff), | ||||||
|                                    flags, srvbuf, sizeof(srvbuf)); |                                    flags, srvbuf, sizeof(srvbuf)); | ||||||
|         callback(arg, ARES_SUCCESS, ipbuf, service); |         callback(arg, ARES_SUCCESS, 0, ipbuf, service); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|     /* This is where a DNS lookup becomes necessary */ |     /* This is where a DNS lookup becomes necessary */ | ||||||
| @@ -161,12 +162,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t | |||||||
|         niquery = malloc(sizeof(struct nameinfo_query)); |         niquery = malloc(sizeof(struct nameinfo_query)); | ||||||
|         if (!niquery) |         if (!niquery) | ||||||
|           { |           { | ||||||
|             callback(arg, ARES_ENOMEM, NULL, NULL); |             callback(arg, ARES_ENOMEM, 0, NULL, NULL); | ||||||
|             return; |             return; | ||||||
|           } |           } | ||||||
|         niquery->callback = callback; |         niquery->callback = callback; | ||||||
|         niquery->arg = arg; |         niquery->arg = arg; | ||||||
|         niquery->flags = flags; |         niquery->flags = flags; | ||||||
|  |         niquery->timeouts = 0; | ||||||
|         if (sa->sa_family == AF_INET) |         if (sa->sa_family == AF_INET) | ||||||
|           { |           { | ||||||
|             niquery->family = AF_INET; |             niquery->family = AF_INET; | ||||||
| @@ -185,13 +187,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void nameinfo_callback(void *arg, int status, struct hostent *host) | static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host) | ||||||
| { | { | ||||||
|   struct nameinfo_query *niquery = (struct nameinfo_query *) arg; |   struct nameinfo_query *niquery = (struct nameinfo_query *) arg; | ||||||
|   char srvbuf[33]; |   char srvbuf[33]; | ||||||
|   char *service = NULL; |   char *service = NULL; | ||||||
|  |  | ||||||
|  |   niquery->timeouts += timeouts; | ||||||
|   if (status == ARES_SUCCESS) |   if (status == ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       /* They want a service too */ |       /* They want a service too */ | ||||||
| @@ -220,7 +222,7 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host) | |||||||
|                  *end = 0; |                  *end = 0; | ||||||
|              } |              } | ||||||
|         } |         } | ||||||
|       niquery->callback(niquery->arg, ARES_SUCCESS, (char *)(host->h_name), |       niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name), | ||||||
|                         service); |                         service); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @@ -247,10 +249,10 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host) | |||||||
|             service = lookup_service(niquery->addr.addr6.sin6_port, |             service = lookup_service(niquery->addr.addr6.sin6_port, | ||||||
|                                      niquery->flags, srvbuf, sizeof(srvbuf)); |                                      niquery->flags, srvbuf, sizeof(srvbuf)); | ||||||
|         } |         } | ||||||
|       niquery->callback(niquery->arg, ARES_SUCCESS, ipbuf, service); |       niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf, service); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   niquery->callback(niquery->arg, status, NULL, NULL); |   niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL); | ||||||
|   free(niquery); |   free(niquery); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ ares_getopt(int nargc, char * const nargv[], const char *ostr) | |||||||
|         } |         } | ||||||
|     }                                         /* option letter okay? */ |     }                                         /* option letter okay? */ | ||||||
|     if ((optopt = (int)*place++) == (int)':' || |     if ((optopt = (int)*place++) == (int)':' || | ||||||
|         !(oli = strchr(ostr, optopt))) { |         (oli = strchr(ostr, optopt)) == NULL) { | ||||||
|         /* |         /* | ||||||
|          * if the user didn't specify '-' as an option, |          * if the user didn't specify '-' as an option, | ||||||
|          * assume it means EOF. |          * assume it means EOF. | ||||||
|   | |||||||
| @@ -34,16 +34,18 @@ int ares_getsock(ares_channel channel, | |||||||
|  |  | ||||||
|   ares_socket_t *socks = (ares_socket_t *)s; |   ares_socket_t *socks = (ares_socket_t *)s; | ||||||
|  |  | ||||||
|   /* No queries, no file descriptors. */ |   /* Are there any active queries? */ | ||||||
|   if (!channel->queries) |   int active_queries = !ares__is_list_empty(&(channel->all_queries)); | ||||||
|     return 0; |  | ||||||
|  |  | ||||||
|   for (i = 0; |   for (i = 0; | ||||||
|        (i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM); |        (i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM); | ||||||
|        i++) |        i++) | ||||||
|     { |     { | ||||||
|       server = &channel->servers[i]; |       server = &channel->servers[i]; | ||||||
|       if (server->udp_socket != ARES_SOCKET_BAD) |       /* We only need to register interest in UDP sockets if we have | ||||||
|  |        * outstanding queries. | ||||||
|  |        */ | ||||||
|  |       if (active_queries && server->udp_socket != ARES_SOCKET_BAD) | ||||||
|         { |         { | ||||||
|           if(sockindex >= numsocks) |           if(sockindex >= numsocks) | ||||||
|             break; |             break; | ||||||
| @@ -51,6 +53,10 @@ int ares_getsock(ares_channel channel, | |||||||
|           bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); |           bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); | ||||||
|           sockindex++; |           sockindex++; | ||||||
|         } |         } | ||||||
|  |       /* We always register for TCP events, because we want to know | ||||||
|  |        * when the other side closes the connection, so we don't waste | ||||||
|  |        * time trying to use a broken connection. | ||||||
|  |        */ | ||||||
|       if (server->tcp_socket != ARES_SOCKET_BAD) |       if (server->tcp_socket != ARES_SOCKET_BAD) | ||||||
|        { |        { | ||||||
|          if(sockindex >= numsocks) |          if(sockindex >= numsocks) | ||||||
| @@ -58,7 +64,7 @@ int ares_getsock(ares_channel channel, | |||||||
|          socks[sockindex] = server->tcp_socket; |          socks[sockindex] = server->tcp_socket; | ||||||
|          bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); |          bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); | ||||||
|  |  | ||||||
|          if (server->qhead) |          if (server->qhead && active_queries) | ||||||
|            /* then the tcp socket is also writable! */ |            /* then the tcp socket is also writable! */ | ||||||
|            bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); |            bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| .\" $Id$ | .\" $Id$ | ||||||
| .\" | .\" | ||||||
| .\" Copyright 1998 by the Massachusetts Institute of Technology. | .\" Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  | .\" Copyright (C) 2007-2008 by Daniel Stenberg | ||||||
| .\" | .\" | ||||||
| .\" Permission to use, copy, modify, and distribute this | .\" Permission to use, copy, modify, and distribute this | ||||||
| .\" software and its documentation for any purpose and without | .\" software and its documentation for any purpose and without | ||||||
| @@ -14,7 +15,7 @@ | |||||||
| .\" this software for any purpose.  It is provided "as is" | .\" this software for any purpose.  It is provided "as is" | ||||||
| .\" without express or implied warranty. | .\" without express or implied warranty. | ||||||
| .\" | .\" | ||||||
| .TH ARES_INIT 3 "7 December 2004" | .TH ARES_INIT 3 "13 May 2008" | ||||||
| .SH NAME | .SH NAME | ||||||
| ares_init, ares_init_options \- Initialize a resolver channel | ares_init, ares_init_options \- Initialize a resolver channel | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| @@ -49,10 +50,22 @@ description of possible flag values. | |||||||
| .B ARES_OPT_TIMEOUT | .B ARES_OPT_TIMEOUT | ||||||
| .B int \fItimeout\fP; | .B int \fItimeout\fP; | ||||||
| .br | .br | ||||||
| The number of seconds each name server is given to respond to a query | The number of seconds each name server is given to respond to a query on the | ||||||
| on the first try.  (After the first try, the timeout algorithm becomes | first try.  (After the first try, the timeout algorithm becomes more | ||||||
| more complicated, but scales linearly with the value of | complicated, but scales linearly with the value of \fItimeout\fP.)  The | ||||||
| \fItimeout\fP.)  The default is five seconds. | default is five seconds. This option is being deprecated by | ||||||
|  | \fIARES_OPT_TIMEOUTMS\fP starting in c-ares 1.5.2. | ||||||
|  | .TP 18 | ||||||
|  | .B ARES_OPT_TIMEOUTMS | ||||||
|  | .B int \fItimeout\fP; | ||||||
|  | .br | ||||||
|  | The number of milliseconds each name server is given to respond to a query on | ||||||
|  | the first try.  (After the first try, the timeout algorithm becomes more | ||||||
|  | complicated, but scales linearly with the value of \fItimeout\fP.)  The | ||||||
|  | default is five seconds. Note that this option is specified with the same | ||||||
|  | struct field as the former \fIARES_OPT_TIMEOUT\fP, it is but the option bits | ||||||
|  | that tell c-ares how to interpret the number. This option was added in c-ares | ||||||
|  | 1.5.2. | ||||||
| .TP 18 | .TP 18 | ||||||
| .B ARES_OPT_TRIES | .B ARES_OPT_TRIES | ||||||
| .B int \fItries\fP; | .B int \fItries\fP; | ||||||
|   | |||||||
							
								
								
									
										272
									
								
								ares/ares_init.c
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								ares/ares_init.c
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | |||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  |  * Copyright (C) 2007-2008 by Daniel Stenberg | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
| @@ -75,7 +76,7 @@ static int config_nameserver(struct server_state **servers, int *nservers, | |||||||
| static int set_search(ares_channel channel, const char *str); | static int set_search(ares_channel channel, const char *str); | ||||||
| static int set_options(ares_channel channel, const char *str); | static int set_options(ares_channel channel, const char *str); | ||||||
| static const char *try_option(const char *p, const char *q, const char *opt); | static const char *try_option(const char *p, const char *q, const char *opt); | ||||||
| static void init_id_key(rc4_key* key,int key_data_len); | static int init_id_key(rc4_key* key,int key_data_len); | ||||||
|  |  | ||||||
| #ifndef WIN32 | #ifndef WIN32 | ||||||
| static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat); | static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat); | ||||||
| @@ -107,6 +108,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | |||||||
|   int i; |   int i; | ||||||
|   int status = ARES_SUCCESS; |   int status = ARES_SUCCESS; | ||||||
|   struct server_state *server; |   struct server_state *server; | ||||||
|  |   struct timeval now; | ||||||
|  |  | ||||||
| #ifdef CURLDEBUG | #ifdef CURLDEBUG | ||||||
|   const char *env = getenv("CARES_MEMDEBUG"); |   const char *env = getenv("CARES_MEMDEBUG"); | ||||||
| @@ -124,6 +126,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | |||||||
|     return ARES_ENOMEM; |     return ARES_ENOMEM; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   now = ares__tvnow(); | ||||||
|  |  | ||||||
|   /* Set everything to distinguished values so we know they haven't |   /* Set everything to distinguished values so we know they haven't | ||||||
|    * been set yet. |    * been set yet. | ||||||
|    */ |    */ | ||||||
| @@ -133,17 +137,32 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | |||||||
|   channel->ndots = -1; |   channel->ndots = -1; | ||||||
|   channel->udp_port = -1; |   channel->udp_port = -1; | ||||||
|   channel->tcp_port = -1; |   channel->tcp_port = -1; | ||||||
|  |   channel->socket_send_buffer_size = -1; | ||||||
|  |   channel->socket_receive_buffer_size = -1; | ||||||
|   channel->nservers = -1; |   channel->nservers = -1; | ||||||
|   channel->ndomains = -1; |   channel->ndomains = -1; | ||||||
|   channel->nsort = -1; |   channel->nsort = -1; | ||||||
|  |   channel->tcp_connection_generation = 0; | ||||||
|   channel->lookups = NULL; |   channel->lookups = NULL; | ||||||
|   channel->queries = NULL; |  | ||||||
|   channel->domains = NULL; |   channel->domains = NULL; | ||||||
|   channel->sortlist = NULL; |   channel->sortlist = NULL; | ||||||
|   channel->servers = NULL; |   channel->servers = NULL; | ||||||
|   channel->sock_state_cb = NULL; |   channel->sock_state_cb = NULL; | ||||||
|   channel->sock_state_cb_data = NULL; |   channel->sock_state_cb_data = NULL; | ||||||
|  |  | ||||||
|  |   channel->last_timeout_processed = (time_t)now.tv_sec; | ||||||
|  |  | ||||||
|  |   /* Initialize our lists of queries */ | ||||||
|  |   ares__init_list_head(&(channel->all_queries)); | ||||||
|  |   for (i = 0; i < ARES_QID_TABLE_SIZE; i++) | ||||||
|  |     { | ||||||
|  |       ares__init_list_head(&(channel->queries_by_qid[i])); | ||||||
|  |     } | ||||||
|  |   for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) | ||||||
|  |     { | ||||||
|  |       ares__init_list_head(&(channel->queries_by_timeout[i])); | ||||||
|  |     } | ||||||
|  |  | ||||||
|   /* Initialize configuration by each of the four sources, from highest |   /* Initialize configuration by each of the four sources, from highest | ||||||
|    * precedence to lowest. |    * precedence to lowest. | ||||||
|    */ |    */ | ||||||
| @@ -172,6 +191,18 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | |||||||
|       DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", |       DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", | ||||||
|                      ares_strerror(status))); |                      ares_strerror(status))); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /* Generate random key */ | ||||||
|  |  | ||||||
|  |   if (status == ARES_SUCCESS) { | ||||||
|  |     status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN); | ||||||
|  |     if (status == ARES_SUCCESS) | ||||||
|  |       channel->next_id = ares__generate_new_id(&channel->id_key); | ||||||
|  |     else | ||||||
|  |       DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", | ||||||
|  |                      ares_strerror(status))); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (status != ARES_SUCCESS) |   if (status != ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       /* Something failed; clean up memory we may have allocated. */ |       /* Something failed; clean up memory we may have allocated. */ | ||||||
| @@ -201,17 +232,16 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | |||||||
|       server = &channel->servers[i]; |       server = &channel->servers[i]; | ||||||
|       server->udp_socket = ARES_SOCKET_BAD; |       server->udp_socket = ARES_SOCKET_BAD; | ||||||
|       server->tcp_socket = ARES_SOCKET_BAD; |       server->tcp_socket = ARES_SOCKET_BAD; | ||||||
|  |       server->tcp_connection_generation = ++channel->tcp_connection_generation; | ||||||
|       server->tcp_lenbuf_pos = 0; |       server->tcp_lenbuf_pos = 0; | ||||||
|       server->tcp_buffer = NULL; |       server->tcp_buffer = NULL; | ||||||
|       server->qhead = NULL; |       server->qhead = NULL; | ||||||
|       server->qtail = NULL; |       server->qtail = NULL; | ||||||
|  |       ares__init_list_head(&(server->queries_to_server)); | ||||||
|  |       server->channel = channel; | ||||||
|  |       server->is_broken = 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   init_id_key(&channel->id_key, ARES_ID_KEY_LEN); |  | ||||||
|  |  | ||||||
|   channel->next_id = ares__generate_new_id(&channel->id_key); |  | ||||||
|   channel->queries = NULL; |  | ||||||
|  |  | ||||||
|   *channelptr = channel; |   *channelptr = channel; | ||||||
|   return ARES_SUCCESS; |   return ARES_SUCCESS; | ||||||
| } | } | ||||||
| @@ -228,34 +258,41 @@ int ares_save_options(ares_channel channel, struct ares_options *options, | |||||||
|   if (!ARES_CONFIG_CHECK(channel)) |   if (!ARES_CONFIG_CHECK(channel)) | ||||||
|     return ARES_ENODATA; |     return ARES_ENODATA; | ||||||
|  |  | ||||||
|   (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TIMEOUT|ARES_OPT_TRIES|ARES_OPT_NDOTS| |   (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS| | ||||||
|                 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB| |                 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB| | ||||||
|                 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS| |                 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS| | ||||||
|                 ARES_OPT_SORTLIST); |                 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS); | ||||||
|  |  | ||||||
|   /* Copy easy stuff */ |   /* Copy easy stuff */ | ||||||
|   options->flags   = channel->flags; |   options->flags   = channel->flags; | ||||||
|  |  | ||||||
|  |   /* We return full millisecond resolution but that's only because we don't | ||||||
|  |      set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */ | ||||||
|   options->timeout = channel->timeout; |   options->timeout = channel->timeout; | ||||||
|   options->tries   = channel->tries; |   options->tries   = channel->tries; | ||||||
|   options->ndots   = channel->ndots; |   options->ndots   = channel->ndots; | ||||||
|   options->udp_port = channel->udp_port; |   options->udp_port = (unsigned short)channel->udp_port; | ||||||
|   options->tcp_port = channel->tcp_port; |   options->tcp_port = (unsigned short)channel->tcp_port; | ||||||
|   options->sock_state_cb     = channel->sock_state_cb; |   options->sock_state_cb     = channel->sock_state_cb; | ||||||
|   options->sock_state_cb_data = channel->sock_state_cb_data; |   options->sock_state_cb_data = channel->sock_state_cb_data; | ||||||
|  |  | ||||||
|   /* Copy servers */ |   /* Copy servers */ | ||||||
|  |   if (channel->nservers) { | ||||||
|     options->servers = |     options->servers = | ||||||
|       malloc(channel->nservers * sizeof(struct server_state)); |       malloc(channel->nservers * sizeof(struct server_state)); | ||||||
|     if (!options->servers && channel->nservers != 0) |     if (!options->servers && channel->nservers != 0) | ||||||
|       return ARES_ENOMEM; |       return ARES_ENOMEM; | ||||||
|     for (i = 0; i < channel->nservers; i++) |     for (i = 0; i < channel->nservers; i++) | ||||||
|       options->servers[i] = channel->servers[i].addr; |       options->servers[i] = channel->servers[i].addr; | ||||||
|  |   } | ||||||
|   options->nservers = channel->nservers; |   options->nservers = channel->nservers; | ||||||
|  |  | ||||||
|   /* copy domains */ |   /* copy domains */ | ||||||
|  |   if (channel->ndomains) { | ||||||
|     options->domains = malloc(channel->ndomains * sizeof(char *)); |     options->domains = malloc(channel->ndomains * sizeof(char *)); | ||||||
|     if (!options->domains) |     if (!options->domains) | ||||||
|       return ARES_ENOMEM; |       return ARES_ENOMEM; | ||||||
|  |  | ||||||
|     for (i = 0; i < channel->ndomains; i++) |     for (i = 0; i < channel->ndomains; i++) | ||||||
|     { |     { | ||||||
|       options->ndomains = i; |       options->ndomains = i; | ||||||
| @@ -263,14 +300,18 @@ int ares_save_options(ares_channel channel, struct ares_options *options, | |||||||
|       if (!options->domains[i]) |       if (!options->domains[i]) | ||||||
|         return ARES_ENOMEM; |         return ARES_ENOMEM; | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|   options->ndomains = channel->ndomains; |   options->ndomains = channel->ndomains; | ||||||
|  |  | ||||||
|   /* copy lookups */ |   /* copy lookups */ | ||||||
|  |   if (channel->lookups) { | ||||||
|     options->lookups = strdup(channel->lookups); |     options->lookups = strdup(channel->lookups); | ||||||
|   if (!options->lookups) |     if (!options->lookups && channel->lookups) | ||||||
|       return ARES_ENOMEM; |       return ARES_ENOMEM; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* copy sortlist */ |   /* copy sortlist */ | ||||||
|  |   if (channel->nsort) { | ||||||
|     options->sortlist = malloc(channel->nsort * sizeof(struct apattern)); |     options->sortlist = malloc(channel->nsort * sizeof(struct apattern)); | ||||||
|     if (!options->sortlist) |     if (!options->sortlist) | ||||||
|       return ARES_ENOMEM; |       return ARES_ENOMEM; | ||||||
| @@ -279,6 +320,7 @@ int ares_save_options(ares_channel channel, struct ares_options *options, | |||||||
|       memcpy(&(options->sortlist[i]), &(channel->sortlist[i]), |       memcpy(&(options->sortlist[i]), &(channel->sortlist[i]), | ||||||
|              sizeof(struct apattern)); |              sizeof(struct apattern)); | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|   options->nsort = channel->nsort; |   options->nsort = channel->nsort; | ||||||
|  |  | ||||||
|   return ARES_SUCCESS; |   return ARES_SUCCESS; | ||||||
| @@ -293,8 +335,10 @@ static int init_by_options(ares_channel channel, | |||||||
|   /* Easy stuff. */ |   /* Easy stuff. */ | ||||||
|   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1) |   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1) | ||||||
|     channel->flags = options->flags; |     channel->flags = options->flags; | ||||||
|   if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1) |   if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1) | ||||||
|     channel->timeout = options->timeout; |     channel->timeout = options->timeout; | ||||||
|  |   else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1) | ||||||
|  |     channel->timeout = options->timeout * 1000; | ||||||
|   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1) |   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1) | ||||||
|     channel->tries = options->tries; |     channel->tries = options->tries; | ||||||
|   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1) |   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1) | ||||||
| @@ -308,6 +352,12 @@ static int init_by_options(ares_channel channel, | |||||||
|       channel->sock_state_cb = options->sock_state_cb; |       channel->sock_state_cb = options->sock_state_cb; | ||||||
|       channel->sock_state_cb_data = options->sock_state_cb_data; |       channel->sock_state_cb_data = options->sock_state_cb_data; | ||||||
|     } |     } | ||||||
|  |   if ((optmask & ARES_OPT_SOCK_SNDBUF) | ||||||
|  |       && channel->socket_send_buffer_size == -1) | ||||||
|  |     channel->socket_send_buffer_size = options->socket_send_buffer_size; | ||||||
|  |   if ((optmask & ARES_OPT_SOCK_RCVBUF) | ||||||
|  |       && channel->socket_receive_buffer_size == -1) | ||||||
|  |     channel->socket_receive_buffer_size = options->socket_receive_buffer_size; | ||||||
|  |  | ||||||
|   /* Copy the servers, if given. */ |   /* Copy the servers, if given. */ | ||||||
|   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1) |   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1) | ||||||
| @@ -456,7 +506,7 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size) | |||||||
|   FIXED_INFO    *fi   = alloca (sizeof(*fi)); |   FIXED_INFO    *fi   = alloca (sizeof(*fi)); | ||||||
|   DWORD          size = sizeof (*fi); |   DWORD          size = sizeof (*fi); | ||||||
|   typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*); |   typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*); | ||||||
|   get_net_param_func GetNetworkParams;  /* available only on Win-98/2000+ */ |   get_net_param_func fpGetNetworkParams;  /* available only on Win-98/2000+ */ | ||||||
|   HMODULE        handle; |   HMODULE        handle; | ||||||
|   IP_ADDR_STRING *ipAddr; |   IP_ADDR_STRING *ipAddr; | ||||||
|   int            i, count = 0; |   int            i, count = 0; | ||||||
| @@ -473,16 +523,16 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size) | |||||||
|   if (!handle) |   if (!handle) | ||||||
|      return (0); |      return (0); | ||||||
|  |  | ||||||
|   GetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams"); |   fpGetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams"); | ||||||
|   if (!GetNetworkParams) |   if (!fpGetNetworkParams) | ||||||
|      goto quit; |      goto quit; | ||||||
|  |  | ||||||
|   res = (*GetNetworkParams) (fi, &size); |   res = (*fpGetNetworkParams) (fi, &size); | ||||||
|   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) |   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) | ||||||
|      goto quit; |      goto quit; | ||||||
|  |  | ||||||
|   fi = alloca (size); |   fi = alloca (size); | ||||||
|   if (!fi || (*GetNetworkParams) (fi, &size) != ERROR_SUCCESS) |   if (!fi || (*fpGetNetworkParams) (fi, &size) != ERROR_SUCCESS) | ||||||
|      goto quit; |      goto quit; | ||||||
|  |  | ||||||
|   if (debug) |   if (debug) | ||||||
| @@ -862,7 +912,8 @@ okay: | |||||||
|  |  | ||||||
| static int init_by_defaults(ares_channel channel) | static int init_by_defaults(ares_channel channel) | ||||||
| { | { | ||||||
|   char hostname[MAXHOSTNAMELEN + 1]; |   char *hostname = NULL; | ||||||
|  |   int rc = ARES_SUCCESS; | ||||||
|  |  | ||||||
|   if (channel->flags == -1) |   if (channel->flags == -1) | ||||||
|     channel->flags = 0; |     channel->flags = 0; | ||||||
| @@ -877,53 +928,103 @@ static int init_by_defaults(ares_channel channel) | |||||||
|   if (channel->tcp_port == -1) |   if (channel->tcp_port == -1) | ||||||
|     channel->tcp_port = htons(NAMESERVER_PORT); |     channel->tcp_port = htons(NAMESERVER_PORT); | ||||||
|  |  | ||||||
|   if (channel->nservers == -1) |   if (channel->nservers == -1) { | ||||||
|     { |  | ||||||
|     /* If nobody specified servers, try a local named. */ |     /* If nobody specified servers, try a local named. */ | ||||||
|     channel->servers = malloc(sizeof(struct server_state)); |     channel->servers = malloc(sizeof(struct server_state)); | ||||||
|       if (!channel->servers) |     if (!channel->servers) { | ||||||
|         return ARES_ENOMEM; |       rc = ARES_ENOMEM; | ||||||
|  |       goto error; | ||||||
|  |     } | ||||||
|     channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK); |     channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK); | ||||||
|     channel->nservers = 1; |     channel->nservers = 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (channel->ndomains == -1) | #ifdef ENAMETOOLONG | ||||||
|     { | #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno)) | ||||||
|  | #else | ||||||
|  | #define toolong(x) (x == -1) && (EINVAL == errno) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   if (channel->ndomains == -1) { | ||||||
|     /* Derive a default domain search list from the kernel hostname, |     /* Derive a default domain search list from the kernel hostname, | ||||||
|      * or set it to empty if the hostname isn't helpful. |      * or set it to empty if the hostname isn't helpful. | ||||||
|      */ |      */ | ||||||
|       if (gethostname(hostname, sizeof(hostname)) == -1 |     size_t len = 64; | ||||||
|           || !strchr(hostname, '.')) |     int res; | ||||||
|         { |  | ||||||
|           channel->ndomains = 0; |     hostname = (char *)malloc(len); | ||||||
|  |     if(!hostname) { | ||||||
|  |       rc = ARES_ENOMEM; | ||||||
|  |       goto error; | ||||||
|     } |     } | ||||||
|       else |  | ||||||
|         { |     do { | ||||||
|  |       res = gethostname(hostname, len); | ||||||
|  |  | ||||||
|  |       if(toolong(res)) { | ||||||
|  |         char *p; | ||||||
|  |         len *= 2; | ||||||
|  |         p = realloc(hostname, len); | ||||||
|  |         if(!p) { | ||||||
|  |           rc = ARES_ENOMEM; | ||||||
|  |           goto error; | ||||||
|  |         } | ||||||
|  |         hostname = p; | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  |       else if(res) { | ||||||
|  |         rc = ARES_EBADNAME; | ||||||
|  |         goto error; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     } while(0); | ||||||
|  |  | ||||||
|  |     channel->ndomains = 0; /* default to none */ | ||||||
|  |     if (strchr(hostname, '.'))  { | ||||||
|  |       /* a dot was found */ | ||||||
|  |  | ||||||
|       channel->domains = malloc(sizeof(char *)); |       channel->domains = malloc(sizeof(char *)); | ||||||
|           if (!channel->domains) |       if (!channel->domains) { | ||||||
|             return ARES_ENOMEM; |         rc = ARES_ENOMEM; | ||||||
|           channel->ndomains = 0; |         goto error; | ||||||
|  |       } | ||||||
|       channel->domains[0] = strdup(strchr(hostname, '.') + 1); |       channel->domains[0] = strdup(strchr(hostname, '.') + 1); | ||||||
|           if (!channel->domains[0]) |       if (!channel->domains[0]) { | ||||||
|             return ARES_ENOMEM; |         rc = ARES_ENOMEM; | ||||||
|  |         goto error; | ||||||
|  |       } | ||||||
|       channel->ndomains = 1; |       channel->ndomains = 1; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (channel->nsort == -1) |   if (channel->nsort == -1) { | ||||||
|     { |  | ||||||
|     channel->sortlist = NULL; |     channel->sortlist = NULL; | ||||||
|     channel->nsort = 0; |     channel->nsort = 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (!channel->lookups) |   if (!channel->lookups) { | ||||||
|     { |  | ||||||
|     channel->lookups = strdup("fb"); |     channel->lookups = strdup("fb"); | ||||||
|     if (!channel->lookups) |     if (!channel->lookups) | ||||||
|         return ARES_ENOMEM; |       rc = ARES_ENOMEM; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return ARES_SUCCESS; |   error: | ||||||
|  |   if(rc) { | ||||||
|  |     if(channel->servers) | ||||||
|  |       free(channel->servers); | ||||||
|  |  | ||||||
|  |     if(channel->domains && channel->domains[0]) | ||||||
|  |       free(channel->domains[0]); | ||||||
|  |     if(channel->domains) | ||||||
|  |       free(channel->domains); | ||||||
|  |     if(channel->lookups) | ||||||
|  |       free(channel->lookups); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(hostname) | ||||||
|  |     free(hostname); | ||||||
|  |  | ||||||
|  |   return rc; | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifndef WIN32 | #ifndef WIN32 | ||||||
| @@ -1204,16 +1305,61 @@ static int set_options(ares_channel channel, const char *str) | |||||||
| static char *try_config(char *s, const char *opt) | static char *try_config(char *s, const char *opt) | ||||||
| { | { | ||||||
|   size_t len; |   size_t len; | ||||||
|  |   ssize_t i; | ||||||
|  |   ssize_t j; | ||||||
|  |   char *p; | ||||||
|  |  | ||||||
|   len = strlen(opt); |   if (!s || !opt) | ||||||
|   if (strncmp(s, opt, len) != 0 || !ISSPACE(s[len])) |     /* no line or no option */ | ||||||
|     return NULL; |     return NULL; | ||||||
|   s += len; |  | ||||||
|   while (ISSPACE(*s)) |  | ||||||
|     s++; |  | ||||||
|   return s; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |   /* trim line comment */ | ||||||
|  |   for (i = 0; s[i] && s[i] != '#'; ++i); | ||||||
|  |   s[i] = '\0'; | ||||||
|  |  | ||||||
|  |   /* trim trailing whitespace */ | ||||||
|  |   for (j = i-1; j >= 0 && ISSPACE(s[j]); --j); | ||||||
|  |   s[++j] = '\0'; | ||||||
|  |  | ||||||
|  |   /* skip leading whitespace */ | ||||||
|  |   for (i = 0; s[i] && ISSPACE(s[i]); ++i); | ||||||
|  |   p = &s[i]; | ||||||
|  |  | ||||||
|  |   if (!*p) | ||||||
|  |     /* empty line */ | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|  |   if ((len = strlen(opt)) == 0) | ||||||
|  |     /* empty option */ | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|  |   if (strncmp(p, opt, len) != 0) | ||||||
|  |     /* line and option do not match */ | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|  |   /* skip over given option name */ | ||||||
|  |   p += len; | ||||||
|  |  | ||||||
|  |   if (!*p) | ||||||
|  |     /* no option value */ | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|  |   if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p)) | ||||||
|  |     /* whitespace between option name and value is mandatory | ||||||
|  |        for given option names which do not end with ':' or '=' */ | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|  |   /* skip over whitespace */ | ||||||
|  |   while (*p && ISSPACE(*p)) | ||||||
|  |     p++; | ||||||
|  |  | ||||||
|  |   if (!*p) | ||||||
|  |     /* no option value */ | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|  |   /* return pointer to option value */ | ||||||
|  |   return p; | ||||||
|  | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| static const char *try_option(const char *p, const char *q, const char *opt) | static const char *try_option(const char *p, const char *q, const char *opt) | ||||||
| @@ -1292,13 +1438,9 @@ static void randomize_key(unsigned char* key,int key_data_len) | |||||||
|   } |   } | ||||||
| #else /* !WIN32 */ | #else /* !WIN32 */ | ||||||
| #ifdef RANDOM_FILE | #ifdef RANDOM_FILE | ||||||
|   char buffer[256]; |  | ||||||
|   FILE *f = fopen(RANDOM_FILE, "rb"); |   FILE *f = fopen(RANDOM_FILE, "rb"); | ||||||
|   if(f) { |   if(f) { | ||||||
|     size_t i; |     counter = fread(key, 1, key_data_len, f); | ||||||
|     size_t rc = fread(buffer, key_data_len, 1, f); |  | ||||||
|     for(i=0; i<rc && counter < key_data_len; i++) |  | ||||||
|       key[counter++]=buffer[i]; |  | ||||||
|     fclose(f); |     fclose(f); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| @@ -1306,11 +1448,11 @@ static void randomize_key(unsigned char* key,int key_data_len) | |||||||
|  |  | ||||||
|   if ( !randomized ) { |   if ( !randomized ) { | ||||||
|     for (;counter<key_data_len;counter++) |     for (;counter<key_data_len;counter++) | ||||||
|       key[counter]=rand() % 256; |       key[counter]=(unsigned char)(rand() % 256); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void init_id_key(rc4_key* key,int key_data_len) | static int init_id_key(rc4_key* key,int key_data_len) | ||||||
| { | { | ||||||
|   unsigned char index1; |   unsigned char index1; | ||||||
|   unsigned char index2; |   unsigned char index2; | ||||||
| @@ -1319,29 +1461,33 @@ static void init_id_key(rc4_key* key,int key_data_len) | |||||||
|   unsigned char *key_data_ptr = 0; |   unsigned char *key_data_ptr = 0; | ||||||
|  |  | ||||||
|   key_data_ptr = calloc(1,key_data_len); |   key_data_ptr = calloc(1,key_data_len); | ||||||
|   randomize_key(key->state,key_data_len); |   if (!key_data_ptr) | ||||||
|  |     return ARES_ENOMEM; | ||||||
|  |  | ||||||
|   state = &key->state[0]; |   state = &key->state[0]; | ||||||
|   for(counter = 0; counter < 256; counter++) |   for(counter = 0; counter < 256; counter++) | ||||||
|         state[counter] = counter; |     /* unnecessary AND but it keeps some compilers happier */ | ||||||
|  |     state[counter] = (unsigned char)(counter & 0xff); | ||||||
|  |   randomize_key(key->state,key_data_len); | ||||||
|   key->x = 0; |   key->x = 0; | ||||||
|   key->y = 0; |   key->y = 0; | ||||||
|   index1 = 0; |   index1 = 0; | ||||||
|   index2 = 0; |   index2 = 0; | ||||||
|   for(counter = 0; counter < 256; counter++) |   for(counter = 0; counter < 256; counter++) | ||||||
|   { |   { | ||||||
|     index2 = (key_data_ptr[index1] + state[counter] + |     index2 = (unsigned char)((key_data_ptr[index1] + state[counter] + | ||||||
|               index2) % 256; |                               index2) % 256); | ||||||
|     ARES_SWAP_BYTE(&state[counter], &state[index2]); |     ARES_SWAP_BYTE(&state[counter], &state[index2]); | ||||||
|  |  | ||||||
|     index1 = (index1 + 1) % key_data_len; |     index1 = (unsigned char)((index1 + 1) % key_data_len); | ||||||
|   } |   } | ||||||
|   free(key_data_ptr); |   free(key_data_ptr); | ||||||
|  |   return ARES_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| short ares__generate_new_id(rc4_key* key) | short ares__generate_new_id(rc4_key* key) | ||||||
| { | { | ||||||
|   short r; |   short r=0; | ||||||
|   ares__rc4(key, (unsigned char *)&r, sizeof(r)); |   ares__rc4(key, (unsigned char *)&r, sizeof(r)); | ||||||
|   return r; |   return r; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* | /* Copyright (C) 2005 by Dominick Meglio | ||||||
|  |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
|  * fee is hereby granted, provided that the above copyright |  * fee is hereby granted, provided that the above copyright | ||||||
| @@ -21,11 +22,13 @@ | |||||||
| #define PF_INET6 AF_INET6 | #define PF_INET6 AF_INET6 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef HAVE_STRUCT_IN6_ADDR | #if !defined(HAVE_STRUCT_IN6_ADDR) && !defined(s6_addr) | ||||||
| struct in6_addr | struct in6_addr { | ||||||
| { |   union { | ||||||
|   unsigned char s6_addr[16]; |     unsigned char _S6_u8[16]; | ||||||
|  |   } _S6_un; | ||||||
| }; | }; | ||||||
|  | #define s6_addr _S6_un._S6_u8 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef HAVE_STRUCT_SOCKADDR_IN6 | #ifndef HAVE_STRUCT_SOCKADDR_IN6 | ||||||
|   | |||||||
							
								
								
									
										87
									
								
								ares/ares_llist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								ares/ares_llist.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | |||||||
|  | /* $Id$ */ | ||||||
|  |  | ||||||
|  | /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "setup.h" | ||||||
|  |  | ||||||
|  | #include "ares.h" | ||||||
|  | #include "ares_private.h" | ||||||
|  |  | ||||||
|  | /* Routines for managing doubly-linked circular linked lists with a | ||||||
|  |  * dummy head. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /* Initialize a new head node */ | ||||||
|  | void ares__init_list_head(struct list_node* head) { | ||||||
|  |   head->prev = head; | ||||||
|  |   head->next = head; | ||||||
|  |   head->data = NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Initialize a list node */ | ||||||
|  | void ares__init_list_node(struct list_node* node, void* d) { | ||||||
|  |   node->prev = NULL; | ||||||
|  |   node->next = NULL; | ||||||
|  |   node->data = d; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Returns true iff the given list is empty */ | ||||||
|  | int ares__is_list_empty(struct list_node* head) { | ||||||
|  |   return ((head->next == head) && (head->prev == head)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Inserts new_node before old_node */ | ||||||
|  | void ares__insert_in_list(struct list_node* new_node, | ||||||
|  |                           struct list_node* old_node) { | ||||||
|  |   new_node->next = old_node; | ||||||
|  |   new_node->prev = old_node->prev; | ||||||
|  |   old_node->prev->next = new_node; | ||||||
|  |   old_node->prev = new_node; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Removes the node from the list it's in, if any */ | ||||||
|  | void ares__remove_from_list(struct list_node* node) { | ||||||
|  |   if (node->next != NULL) { | ||||||
|  |     node->prev->next = node->next; | ||||||
|  |     node->next->prev = node->prev; | ||||||
|  |     node->prev = NULL; | ||||||
|  |     node->next = NULL; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Swap the contents of two lists */ | ||||||
|  | void ares__swap_lists(struct list_node* head_a, | ||||||
|  |                       struct list_node* head_b) { | ||||||
|  |   int is_a_empty = ares__is_list_empty(head_a); | ||||||
|  |   int is_b_empty = ares__is_list_empty(head_b); | ||||||
|  |   struct list_node old_a = *head_a; | ||||||
|  |   struct list_node old_b = *head_b; | ||||||
|  |  | ||||||
|  |   if (is_a_empty) { | ||||||
|  |     ares__init_list_head(head_b); | ||||||
|  |   } else { | ||||||
|  |     *head_b = old_a; | ||||||
|  |     old_a.next->prev = head_b; | ||||||
|  |     old_a.prev->next = head_b; | ||||||
|  |   } | ||||||
|  |   if (is_b_empty) { | ||||||
|  |     ares__init_list_head(head_a); | ||||||
|  |   } else { | ||||||
|  |     *head_a = old_b; | ||||||
|  |     old_b.next->prev = head_a; | ||||||
|  |     old_b.prev->next = head_a; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								ares/ares_llist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								ares/ares_llist.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | #ifndef __ARES_LLIST_H | ||||||
|  | #define __ARES_LLIST_H | ||||||
|  |  | ||||||
|  | /* $Id$ */ | ||||||
|  |  | ||||||
|  | /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  |  * | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Node definition for circular, doubly-linked list */ | ||||||
|  | struct list_node { | ||||||
|  |   struct list_node *prev; | ||||||
|  |   struct list_node *next; | ||||||
|  |   void* data; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void ares__init_list_head(struct list_node* head); | ||||||
|  |  | ||||||
|  | void ares__init_list_node(struct list_node* node, void* d); | ||||||
|  |  | ||||||
|  | int ares__is_list_empty(struct list_node* head); | ||||||
|  |  | ||||||
|  | void ares__insert_in_list(struct list_node* new_node, | ||||||
|  |                           struct list_node* old_node); | ||||||
|  |  | ||||||
|  | void ares__remove_from_list(struct list_node* node); | ||||||
|  |  | ||||||
|  | void ares__swap_lists(struct list_node* head_a, | ||||||
|  |                       struct list_node* head_b); | ||||||
|  |  | ||||||
|  | #endif /* __ARES_LLIST_H */ | ||||||
| @@ -88,6 +88,10 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, | |||||||
|   unsigned char *q; |   unsigned char *q; | ||||||
|   const char *p; |   const char *p; | ||||||
|  |  | ||||||
|  |   /* Set our results early, in case we bail out early with an error. */ | ||||||
|  |   *buflen = 0; | ||||||
|  |   *buf = NULL; | ||||||
|  |  | ||||||
|   /* Compute the length of the encoded name so we can check buflen. |   /* Compute the length of the encoded name so we can check buflen. | ||||||
|    * Start counting at 1 for the zero-length label at the end. */ |    * Start counting at 1 for the zero-length label at the end. */ | ||||||
|   len = 1; |   len = 1; | ||||||
| @@ -104,6 +108,23 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, | |||||||
|   if (*name && *(p - 1) != '.') |   if (*name && *(p - 1) != '.') | ||||||
|     len++; |     len++; | ||||||
|  |  | ||||||
|  |   /* Immediately reject names that are longer than the maximum of 255 | ||||||
|  |    * bytes that's specified in RFC 1035 ("To simplify implementations, | ||||||
|  |    * the total length of a domain name (i.e., label octets and label | ||||||
|  |    * length octets) is restricted to 255 octets or less."). We aren't | ||||||
|  |    * doing this just to be a stickler about RFCs. For names that are | ||||||
|  |    * too long, 'dnscache' closes its TCP connection to us immediately | ||||||
|  |    * (when using TCP) and ignores the request when using UDP, and | ||||||
|  |    * BIND's named returns ServFail (TCP or UDP). Sending a request | ||||||
|  |    * that we know will cause 'dnscache' to close the TCP connection is | ||||||
|  |    * painful, since that makes any other outstanding requests on that | ||||||
|  |    * connection fail. And sending a UDP request that we know | ||||||
|  |    * 'dnscache' will ignore is bad because resources will be tied up | ||||||
|  |    * until we time-out the request. | ||||||
|  |    */ | ||||||
|  |   if (len > MAXCDNAME) | ||||||
|  |     return ARES_EBADNAME; | ||||||
|  |  | ||||||
|   *buflen = len + HFIXEDSZ + QFIXEDSZ; |   *buflen = len + HFIXEDSZ + QFIXEDSZ; | ||||||
|   *buf = malloc(*buflen); |   *buf = malloc(*buflen); | ||||||
|   if (!*buf) |   if (!*buf) | ||||||
|   | |||||||
| @@ -22,24 +22,39 @@ ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, | .B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, | ||||||
| .B 	struct hostent **\fIhost\fP); | .B 	struct hostent **\fIhost\fP, | ||||||
|  | .B      struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB); | ||||||
| .fi | .fi | ||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| The | The | ||||||
| .B ares_parse_a_reply | .B ares_parse_a_reply | ||||||
| function parses the response to a query of type A into a | function parses the response to a query of type A into a | ||||||
| .BR "struct hostent" . | .BR "struct hostent" | ||||||
|  | and/or an array of | ||||||
|  | .BR "struct addrttls" .  | ||||||
| The parameters | The parameters | ||||||
| .I abuf | .I abuf | ||||||
| and | and | ||||||
| .I alen | .I alen | ||||||
| give the contents of the response.  The result is stored in allocated | give the contents of the response.  The result is stored in allocated | ||||||
| memory and a pointer to it stored into the variable pointed to by | memory and a pointer to it stored into the variable pointed to by | ||||||
| .IR host . | .IR host , | ||||||
|  | if host is nonnull. | ||||||
| It is the caller's responsibility to free the resulting host structure | It is the caller's responsibility to free the resulting host structure | ||||||
| using | using | ||||||
| .BR ares_free_hostent (3) | .BR ares_free_hostent (3) | ||||||
| when it is no longer needed. | when it is no longer needed. | ||||||
|  | .PP | ||||||
|  | If | ||||||
|  | .IR addrttls | ||||||
|  | and | ||||||
|  | .IR naddrttls | ||||||
|  | are both nonnull, | ||||||
|  | then up to *naddrttls | ||||||
|  | .BR "struct addrttl" | ||||||
|  | records are stored in the array pointed to by addrttls, | ||||||
|  | and then *naddrttls is set to the number of records so stored. | ||||||
|  | Note that the memory for these records is supplied by the caller. | ||||||
| .SH RETURN VALUES | .SH RETURN VALUES | ||||||
| .B ares_parse_a_reply | .B ares_parse_a_reply | ||||||
| can return any of the following values: | can return any of the following values: | ||||||
|   | |||||||
| @@ -29,27 +29,38 @@ | |||||||
| #include <arpa/nameser_compat.h> | #include <arpa/nameser_compat.h> | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <limits.h> | ||||||
| #include "ares.h" | #include "ares.h" | ||||||
| #include "ares_dns.h" | #include "ares_dns.h" | ||||||
| #include "ares_private.h" | #include "ares_private.h" | ||||||
|  |  | ||||||
| int ares_parse_a_reply(const unsigned char *abuf, int alen, | int ares_parse_a_reply(const unsigned char *abuf, int alen, | ||||||
|                        struct hostent **host) |                        struct hostent **host, | ||||||
|  |                        struct addrttl *addrttls, int *naddrttls) | ||||||
| { | { | ||||||
|   unsigned int qdcount, ancount; |   unsigned int qdcount, ancount; | ||||||
|   int status, i, rr_type, rr_class, rr_len, naddrs; |   int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; | ||||||
|  |   int cname_ttl = INT_MAX;  /* the TTL imposed by the CNAME chain */ | ||||||
|   int naliases; |   int naliases; | ||||||
|   long len; |   long len; | ||||||
|   const unsigned char *aptr; |   const unsigned char *aptr; | ||||||
|   char *hostname, *rr_name, *rr_data, **aliases; |   char *hostname, *rr_name, *rr_data, **aliases; | ||||||
|   struct in_addr *addrs; |   struct in_addr *addrs; | ||||||
|   struct hostent *hostent; |   struct hostent *hostent; | ||||||
|  |   const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; | ||||||
|  |  | ||||||
|   /* Set *host to NULL for all failure cases. */ |   /* Set *host to NULL for all failure cases. */ | ||||||
|  |   if (host) | ||||||
|     *host = NULL; |     *host = NULL; | ||||||
|  |   /* Same with *naddrttls. */ | ||||||
|  |   if (naddrttls) | ||||||
|  |     *naddrttls = 0; | ||||||
|  |  | ||||||
|   /* Give up if abuf doesn't have room for a header. */ |   /* Give up if abuf doesn't have room for a header. */ | ||||||
|   if (alen < HFIXEDSZ) |   if (alen < HFIXEDSZ) | ||||||
| @@ -73,6 +84,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|     } |     } | ||||||
|   aptr += len + QFIXEDSZ; |   aptr += len + QFIXEDSZ; | ||||||
|  |  | ||||||
|  |   if (host) | ||||||
|  |     { | ||||||
|       /* Allocate addresses and aliases; ancount gives an upper bound for both. */ |       /* Allocate addresses and aliases; ancount gives an upper bound for both. */ | ||||||
|       addrs = malloc(ancount * sizeof(struct in_addr)); |       addrs = malloc(ancount * sizeof(struct in_addr)); | ||||||
|       if (!addrs) |       if (!addrs) | ||||||
| @@ -87,6 +100,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|           free(addrs); |           free(addrs); | ||||||
|           return ARES_ENOMEM; |           return ARES_ENOMEM; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       addrs = NULL; | ||||||
|  |       aliases = NULL; | ||||||
|  |     } | ||||||
|  |    | ||||||
|   naddrs = 0; |   naddrs = 0; | ||||||
|   naliases = 0; |   naliases = 0; | ||||||
|  |  | ||||||
| @@ -106,13 +126,33 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|       rr_type = DNS_RR_TYPE(aptr); |       rr_type = DNS_RR_TYPE(aptr); | ||||||
|       rr_class = DNS_RR_CLASS(aptr); |       rr_class = DNS_RR_CLASS(aptr); | ||||||
|       rr_len = DNS_RR_LEN(aptr); |       rr_len = DNS_RR_LEN(aptr); | ||||||
|  |       rr_ttl = DNS_RR_TTL(aptr); | ||||||
|       aptr += RRFIXEDSZ; |       aptr += RRFIXEDSZ; | ||||||
|  |  | ||||||
|       if (rr_class == C_IN && rr_type == T_A |       if (rr_class == C_IN && rr_type == T_A | ||||||
|           && rr_len == sizeof(struct in_addr) |           && rr_len == sizeof(struct in_addr) | ||||||
|           && strcasecmp(rr_name, hostname) == 0) |           && strcasecmp(rr_name, hostname) == 0) | ||||||
|         { |         { | ||||||
|  |           if (addrs) | ||||||
|  |             { | ||||||
|  |               if (aptr + sizeof(struct in_addr) > abuf + alen) | ||||||
|  |               { | ||||||
|  |                 status = ARES_EBADRESP; | ||||||
|  |                 break; | ||||||
|  |               } | ||||||
|               memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); |               memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); | ||||||
|  |             } | ||||||
|  |           if (naddrs < max_addr_ttls) | ||||||
|  |             { | ||||||
|  |               struct addrttl * const at = &addrttls[naddrs]; | ||||||
|  |               if (aptr + sizeof(struct in_addr) > abuf + alen) | ||||||
|  |               { | ||||||
|  |                 status = ARES_EBADRESP; | ||||||
|  |                 break; | ||||||
|  |               } | ||||||
|  |               memcpy(&at->ipaddr, aptr,  sizeof(struct in_addr)); | ||||||
|  |               at->ttl = rr_ttl; | ||||||
|  |             } | ||||||
|           naddrs++; |           naddrs++; | ||||||
|           status = ARES_SUCCESS; |           status = ARES_SUCCESS; | ||||||
|         } |         } | ||||||
| @@ -120,7 +160,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|       if (rr_class == C_IN && rr_type == T_CNAME) |       if (rr_class == C_IN && rr_type == T_CNAME) | ||||||
|         { |         { | ||||||
|           /* Record the RR name as an alias. */ |           /* Record the RR name as an alias. */ | ||||||
|  |           if (aliases) | ||||||
|             aliases[naliases] = rr_name; |             aliases[naliases] = rr_name; | ||||||
|  |           else | ||||||
|  |             free(rr_name); | ||||||
|           naliases++; |           naliases++; | ||||||
|  |  | ||||||
|           /* Decode the RR data and replace the hostname with it. */ |           /* Decode the RR data and replace the hostname with it. */ | ||||||
| @@ -129,6 +172,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|             break; |             break; | ||||||
|           free(hostname); |           free(hostname); | ||||||
|           hostname = rr_data; |           hostname = rr_data; | ||||||
|  |  | ||||||
|  |           /* Take the min of the TTLs we see in the CNAME chain. */ | ||||||
|  |           if (cname_ttl > rr_ttl) | ||||||
|  |             cname_ttl = rr_ttl; | ||||||
|         } |         } | ||||||
|       else |       else | ||||||
|         free(rr_name); |         free(rr_name); | ||||||
| @@ -145,8 +192,23 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|     status = ARES_ENODATA; |     status = ARES_ENODATA; | ||||||
|   if (status == ARES_SUCCESS) |   if (status == ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       /* We got our answer.  Allocate memory to build the host entry. */ |       /* We got our answer. */ | ||||||
|  |       if (naddrttls) | ||||||
|  |         { | ||||||
|  |           const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; | ||||||
|  |           for (i = 0; i < n; i++) | ||||||
|  |             { | ||||||
|  |               /* Ensure that each A TTL is no larger than the CNAME TTL. */ | ||||||
|  |               if (addrttls[i].ttl > cname_ttl) | ||||||
|  |                 addrttls[i].ttl = cname_ttl; | ||||||
|  |             } | ||||||
|  |           *naddrttls = n; | ||||||
|  |         } | ||||||
|  |       if (aliases) | ||||||
|         aliases[naliases] = NULL; |         aliases[naliases] = NULL; | ||||||
|  |       if (host) | ||||||
|  |         { | ||||||
|  |           /* Allocate memory to build the host entry. */ | ||||||
|           hostent = malloc(sizeof(struct hostent)); |           hostent = malloc(sizeof(struct hostent)); | ||||||
|           if (hostent) |           if (hostent) | ||||||
|             { |             { | ||||||
| @@ -168,9 +230,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, | |||||||
|             } |             } | ||||||
|           status = ARES_ENOMEM; |           status = ARES_ENOMEM; | ||||||
|         } |         } | ||||||
|  |      } | ||||||
|  |   if (aliases) | ||||||
|  |     { | ||||||
|       for (i = 0; i < naliases; i++) |       for (i = 0; i < naliases; i++) | ||||||
|         free(aliases[i]); |         free(aliases[i]); | ||||||
|       free(aliases); |       free(aliases); | ||||||
|  |     } | ||||||
|   free(addrs); |   free(addrs); | ||||||
|   free(hostname); |   free(hostname); | ||||||
|   return status; |   return status; | ||||||
|   | |||||||
| @@ -22,24 +22,39 @@ ares_parse_aaaa_reply \- Parse a reply to a DNS query of type AAAA into a hosten | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, | .B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, | ||||||
| .B 	struct hostent **\fIhost\fP); | .B 	struct hostent **\fIhost\fP,          | ||||||
|  | .B      struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB); | ||||||
| .fi | .fi | ||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| The | The | ||||||
| .B ares_parse_aaaa_reply | .B ares_parse_aaaa_reply | ||||||
| function parses the response to a query of type AAAA into a | function parses the response to a query of type AAAA into a | ||||||
| .BR "struct hostent" . | .BR "struct hostent" | ||||||
|  | and/or an array of | ||||||
|  | .BR "struct addrttls" .  | ||||||
| The parameters | The parameters | ||||||
| .I abuf | .I abuf | ||||||
| and | and | ||||||
| .I alen | .I alen | ||||||
| give the contents of the response.  The result is stored in allocated | give the contents of the response.  The result is stored in allocated | ||||||
| memory and a pointer to it stored into the variable pointed to by | memory and a pointer to it stored into the variable pointed to by | ||||||
| .IR host . | .IR host , | ||||||
|  | if host is nonnull. | ||||||
| It is the caller's responsibility to free the resulting host structure | It is the caller's responsibility to free the resulting host structure | ||||||
| using | using | ||||||
| .BR ares_free_hostent (3) | .BR ares_free_hostent (3) | ||||||
| when it is no longer needed. | when it is no longer needed. | ||||||
|  | .PP | ||||||
|  | If | ||||||
|  | .IR addrttls | ||||||
|  | and | ||||||
|  | .IR naddrttls | ||||||
|  | are both nonnull, | ||||||
|  | then up to *naddrttls | ||||||
|  | .BR "struct addr6ttl" | ||||||
|  | records are stored in the array pointed to by addrttls, | ||||||
|  | and then *naddrttls is set to the number of records so stored. | ||||||
|  | Note that the memory for these records is supplied by the caller. | ||||||
| .SH RETURN VALUES | .SH RETURN VALUES | ||||||
| .B ares_parse_aaaa_reply | .B ares_parse_aaaa_reply | ||||||
| can return any of the following values: | can return any of the following values: | ||||||
|   | |||||||
| @@ -31,28 +31,39 @@ | |||||||
| #include <arpa/nameser_compat.h> | #include <arpa/nameser_compat.h> | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <limits.h> | ||||||
| #include "ares.h" | #include "ares.h" | ||||||
| #include "ares_dns.h" | #include "ares_dns.h" | ||||||
| #include "inet_net_pton.h" | #include "inet_net_pton.h" | ||||||
| #include "ares_private.h" | #include "ares_private.h" | ||||||
|  |  | ||||||
| int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | ||||||
|                        struct hostent **host) |                           struct hostent **host, struct addr6ttl *addrttls, | ||||||
|  |                           int *naddrttls) | ||||||
| { | { | ||||||
|   unsigned int qdcount, ancount; |   unsigned int qdcount, ancount; | ||||||
|   int status, i, rr_type, rr_class, rr_len, naddrs; |   int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; | ||||||
|  |   int cname_ttl = INT_MAX;  /* the TTL imposed by the CNAME chain */ | ||||||
|   int naliases; |   int naliases; | ||||||
|   long len; |   long len; | ||||||
|   const unsigned char *aptr; |   const unsigned char *aptr; | ||||||
|   char *hostname, *rr_name, *rr_data, **aliases; |   char *hostname, *rr_name, *rr_data, **aliases; | ||||||
|   struct in6_addr *addrs; |   struct in6_addr *addrs; | ||||||
|   struct hostent *hostent; |   struct hostent *hostent; | ||||||
|  |   const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; | ||||||
|  |  | ||||||
|   /* Set *host to NULL for all failure cases. */ |   /* Set *host to NULL for all failure cases. */ | ||||||
|  |   if (host) | ||||||
|     *host = NULL; |     *host = NULL; | ||||||
|  |   /* Same with *naddrttls. */ | ||||||
|  |   if (naddrttls) | ||||||
|  |     *naddrttls = 0; | ||||||
|  |  | ||||||
|   /* Give up if abuf doesn't have room for a header. */ |   /* Give up if abuf doesn't have room for a header. */ | ||||||
|   if (alen < HFIXEDSZ) |   if (alen < HFIXEDSZ) | ||||||
| @@ -77,6 +88,8 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|   aptr += len + QFIXEDSZ; |   aptr += len + QFIXEDSZ; | ||||||
|  |  | ||||||
|   /* Allocate addresses and aliases; ancount gives an upper bound for both. */ |   /* Allocate addresses and aliases; ancount gives an upper bound for both. */ | ||||||
|  |   if (host) | ||||||
|  |     { | ||||||
|       addrs = malloc(ancount * sizeof(struct in6_addr)); |       addrs = malloc(ancount * sizeof(struct in6_addr)); | ||||||
|       if (!addrs) |       if (!addrs) | ||||||
|         { |         { | ||||||
| @@ -90,6 +103,12 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|           free(addrs); |           free(addrs); | ||||||
|           return ARES_ENOMEM; |           return ARES_ENOMEM; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       addrs = NULL; | ||||||
|  |       aliases = NULL; | ||||||
|  |     } | ||||||
|   naddrs = 0; |   naddrs = 0; | ||||||
|   naliases = 0; |   naliases = 0; | ||||||
|  |  | ||||||
| @@ -109,13 +128,33 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|       rr_type = DNS_RR_TYPE(aptr); |       rr_type = DNS_RR_TYPE(aptr); | ||||||
|       rr_class = DNS_RR_CLASS(aptr); |       rr_class = DNS_RR_CLASS(aptr); | ||||||
|       rr_len = DNS_RR_LEN(aptr); |       rr_len = DNS_RR_LEN(aptr); | ||||||
|  |       rr_ttl = DNS_RR_TTL(aptr); | ||||||
|       aptr += RRFIXEDSZ; |       aptr += RRFIXEDSZ; | ||||||
|  |  | ||||||
|       if (rr_class == C_IN && rr_type == T_AAAA |       if (rr_class == C_IN && rr_type == T_AAAA | ||||||
|           && rr_len == sizeof(struct in6_addr) |           && rr_len == sizeof(struct in6_addr) | ||||||
|           && strcasecmp(rr_name, hostname) == 0) |           && strcasecmp(rr_name, hostname) == 0) | ||||||
|         { |         { | ||||||
|  |           if (addrs) | ||||||
|  |             { | ||||||
|  |               if (aptr + sizeof(struct in6_addr) > abuf + alen) | ||||||
|  |               { | ||||||
|  |                 status = ARES_EBADRESP; | ||||||
|  |                 break; | ||||||
|  |               } | ||||||
|               memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr)); |               memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr)); | ||||||
|  |             } | ||||||
|  |           if (naddrs < max_addr_ttls) | ||||||
|  |             { | ||||||
|  |               struct addr6ttl * const at = &addrttls[naddrs]; | ||||||
|  |               if (aptr + sizeof(struct in6_addr) > abuf + alen) | ||||||
|  |               { | ||||||
|  |                 status = ARES_EBADRESP; | ||||||
|  |                 break; | ||||||
|  |               } | ||||||
|  |               memcpy(&at->ip6addr, aptr,  sizeof(struct in6_addr)); | ||||||
|  |               at->ttl = rr_ttl; | ||||||
|  |             } | ||||||
|           naddrs++; |           naddrs++; | ||||||
|           status = ARES_SUCCESS; |           status = ARES_SUCCESS; | ||||||
|         } |         } | ||||||
| @@ -123,7 +162,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|       if (rr_class == C_IN && rr_type == T_CNAME) |       if (rr_class == C_IN && rr_type == T_CNAME) | ||||||
|         { |         { | ||||||
|           /* Record the RR name as an alias. */ |           /* Record the RR name as an alias. */ | ||||||
|  |           if (aliases) | ||||||
|             aliases[naliases] = rr_name; |             aliases[naliases] = rr_name; | ||||||
|  |           else | ||||||
|  |             free(rr_name); | ||||||
|           naliases++; |           naliases++; | ||||||
|  |  | ||||||
|           /* Decode the RR data and replace the hostname with it. */ |           /* Decode the RR data and replace the hostname with it. */ | ||||||
| @@ -132,6 +174,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|             break; |             break; | ||||||
|           free(hostname); |           free(hostname); | ||||||
|           hostname = rr_data; |           hostname = rr_data; | ||||||
|  |  | ||||||
|  |           /* Take the min of the TTLs we see in the CNAME chain. */ | ||||||
|  |           if (cname_ttl > rr_ttl) | ||||||
|  |             cname_ttl = rr_ttl; | ||||||
|         } |         } | ||||||
|       else |       else | ||||||
|         free(rr_name); |         free(rr_name); | ||||||
| @@ -148,8 +194,23 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|     status = ARES_ENODATA; |     status = ARES_ENODATA; | ||||||
|   if (status == ARES_SUCCESS) |   if (status == ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       /* We got our answer.  Allocate memory to build the host entry. */ |       /* We got our answer. */ | ||||||
|  |       if (naddrttls) | ||||||
|  |         { | ||||||
|  |           const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; | ||||||
|  |           for (i = 0; i < n; i++) | ||||||
|  |             { | ||||||
|  |               /* Ensure that each A TTL is no larger than the CNAME TTL. */ | ||||||
|  |               if (addrttls[i].ttl > cname_ttl) | ||||||
|  |                 addrttls[i].ttl = cname_ttl; | ||||||
|  |             } | ||||||
|  |           *naddrttls = n; | ||||||
|  |         } | ||||||
|  |       if (aliases) | ||||||
|         aliases[naliases] = NULL; |         aliases[naliases] = NULL; | ||||||
|  |       if (host) | ||||||
|  |         { | ||||||
|  |           /* Allocate memory to build the host entry. */ | ||||||
|           hostent = malloc(sizeof(struct hostent)); |           hostent = malloc(sizeof(struct hostent)); | ||||||
|           if (hostent) |           if (hostent) | ||||||
|             { |             { | ||||||
| @@ -171,9 +232,13 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, | |||||||
|             } |             } | ||||||
|           status = ARES_ENOMEM; |           status = ARES_ENOMEM; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |   if (aliases) | ||||||
|  |     { | ||||||
|       for (i = 0; i < naliases; i++) |       for (i = 0; i < naliases; i++) | ||||||
|         free(aliases[i]); |         free(aliases[i]); | ||||||
|       free(aliases); |       free(aliases); | ||||||
|  |     } | ||||||
|   free(addrs); |   free(addrs); | ||||||
|   free(hostname); |   free(hostname); | ||||||
|   return status; |   return status; | ||||||
|   | |||||||
| @@ -28,6 +28,9 @@ | |||||||
| #include <arpa/nameser_compat.h> | #include <arpa/nameser_compat.h> | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| @@ -44,6 +47,8 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | |||||||
|   const unsigned char *aptr; |   const unsigned char *aptr; | ||||||
|   char *ptrname, *hostname, *rr_name, *rr_data; |   char *ptrname, *hostname, *rr_name, *rr_data; | ||||||
|   struct hostent *hostent; |   struct hostent *hostent; | ||||||
|  |   int aliascnt = 0; | ||||||
|  |   char ** aliases; | ||||||
|  |  | ||||||
|   /* Set *host to NULL for all failure cases. */ |   /* Set *host to NULL for all failure cases. */ | ||||||
|   *host = NULL; |   *host = NULL; | ||||||
| @@ -72,6 +77,12 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | |||||||
|  |  | ||||||
|   /* Examine each answer resource record (RR) in turn. */ |   /* Examine each answer resource record (RR) in turn. */ | ||||||
|   hostname = NULL; |   hostname = NULL; | ||||||
|  |   aliases = (char **) malloc(8 * sizeof(char *)); | ||||||
|  |   if (!aliases) | ||||||
|  |     { | ||||||
|  |       free(ptrname); | ||||||
|  |       return ARES_ENOMEM; | ||||||
|  |     } | ||||||
|   for (i = 0; i < (int)ancount; i++) |   for (i = 0; i < (int)ancount; i++) | ||||||
|     { |     { | ||||||
|       /* Decode the RR up to the data field. */ |       /* Decode the RR up to the data field. */ | ||||||
| @@ -99,6 +110,16 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | |||||||
|           if (hostname) |           if (hostname) | ||||||
|             free(hostname); |             free(hostname); | ||||||
|           hostname = rr_data; |           hostname = rr_data; | ||||||
|  |           aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char *)); | ||||||
|  |           if (!aliases[aliascnt]) | ||||||
|  |             { | ||||||
|  |               status = ARES_ENOMEM; | ||||||
|  |               break; | ||||||
|  |             } | ||||||
|  |           strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1); | ||||||
|  |           aliascnt++; | ||||||
|  |           if ((aliascnt%8)==0) | ||||||
|  |             aliases = (char **) realloc(aliases, (aliascnt/16+1) * sizeof(char *)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|       if (rr_class == C_IN && rr_type == T_CNAME) |       if (rr_class == C_IN && rr_type == T_CNAME) | ||||||
| @@ -134,17 +155,20 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | |||||||
|               hostent->h_addr_list[0] = malloc(addrlen); |               hostent->h_addr_list[0] = malloc(addrlen); | ||||||
|               if (hostent->h_addr_list[0]) |               if (hostent->h_addr_list[0]) | ||||||
|                 { |                 { | ||||||
|                   hostent->h_aliases = malloc(sizeof (char *)); |                   hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *)); | ||||||
|                   if (hostent->h_aliases) |                   if (hostent->h_aliases) | ||||||
|                     { |                     { | ||||||
|                       /* Fill in the hostent and return successfully. */ |                       /* Fill in the hostent and return successfully. */ | ||||||
|                       hostent->h_name = hostname; |                       hostent->h_name = hostname; | ||||||
|                       hostent->h_aliases[0] = NULL; |                       for (i=0 ; i<aliascnt ; i++) | ||||||
|  |                         hostent->h_aliases[i] = aliases[i]; | ||||||
|  |                       hostent->h_aliases[aliascnt] = NULL; | ||||||
|                       hostent->h_addrtype = family; |                       hostent->h_addrtype = family; | ||||||
|                       hostent->h_length = addrlen; |                       hostent->h_length = addrlen; | ||||||
|                       memcpy(hostent->h_addr_list[0], addr, addrlen); |                       memcpy(hostent->h_addr_list[0], addr, addrlen); | ||||||
|                       hostent->h_addr_list[1] = NULL; |                       hostent->h_addr_list[1] = NULL; | ||||||
|                       *host = hostent; |                       *host = hostent; | ||||||
|  |                       free(aliases); | ||||||
|                       free(ptrname); |                       free(ptrname); | ||||||
|                       return ARES_SUCCESS; |                       return ARES_SUCCESS; | ||||||
|                     } |                     } | ||||||
| @@ -156,6 +180,10 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, | |||||||
|         } |         } | ||||||
|       status = ARES_ENOMEM; |       status = ARES_ENOMEM; | ||||||
|     } |     } | ||||||
|  |   for (i=0 ; i<aliascnt ; i++) | ||||||
|  |     if (aliases[i])  | ||||||
|  |       free(aliases[i]); | ||||||
|  |   free(aliases); | ||||||
|   if (hostname) |   if (hostname) | ||||||
|     free(hostname); |     free(hostname); | ||||||
|   free(ptrname); |   free(ptrname); | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  |  * Copyright (C) 2004-2008 by Daniel Stenberg | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
| @@ -18,6 +19,14 @@ | |||||||
|  * without express or implied warranty. |  * without express or implied warranty. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Define WIN32 when build target is Win32 API | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) | ||||||
|  | #define WIN32 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
|  |  | ||||||
| @@ -40,7 +49,7 @@ | |||||||
| #include <time.h> | #include <time.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define DEFAULT_TIMEOUT         5 | #define DEFAULT_TIMEOUT         5000 /* milliseconds */ | ||||||
| #define DEFAULT_TRIES           4 | #define DEFAULT_TRIES           4 | ||||||
| #ifndef INADDR_NONE | #ifndef INADDR_NONE | ||||||
| #define INADDR_NONE 0xffffffff | #define INADDR_NONE 0xffffffff | ||||||
| @@ -83,12 +92,20 @@ | |||||||
| #define ARES_ID_KEY_LEN 31 | #define ARES_ID_KEY_LEN 31 | ||||||
|  |  | ||||||
| #include "ares_ipv6.h" | #include "ares_ipv6.h" | ||||||
|  | #include "ares_llist.h" | ||||||
|  |  | ||||||
|  | struct query; | ||||||
|  |  | ||||||
| struct send_request { | struct send_request { | ||||||
|   /* Remaining data to send */ |   /* Remaining data to send */ | ||||||
|   const unsigned char *data; |   const unsigned char *data; | ||||||
|   size_t len; |   size_t len; | ||||||
|  |  | ||||||
|  |   /* The query for which we're sending this data */ | ||||||
|  |   struct query* owner_query; | ||||||
|  |   /* The buffer we're using, if we have our own copy of the packet */ | ||||||
|  |   unsigned char *data_storage; | ||||||
|  |  | ||||||
|   /* Next request in queue */ |   /* Next request in queue */ | ||||||
|   struct send_request *next; |   struct send_request *next; | ||||||
| }; | }; | ||||||
| @@ -110,12 +127,41 @@ struct server_state { | |||||||
|   /* TCP output queue */ |   /* TCP output queue */ | ||||||
|   struct send_request *qhead; |   struct send_request *qhead; | ||||||
|   struct send_request *qtail; |   struct send_request *qtail; | ||||||
|  |  | ||||||
|  |   /* Which incarnation of this connection is this? We don't want to | ||||||
|  |    * retransmit requests into the very same socket, but if the server | ||||||
|  |    * closes on us and we re-open the connection, then we do want to | ||||||
|  |    * re-send. */ | ||||||
|  |   int tcp_connection_generation; | ||||||
|  |  | ||||||
|  |   /* Circular, doubly-linked list of outstanding queries to this server */ | ||||||
|  |   struct list_node queries_to_server; | ||||||
|  |  | ||||||
|  |   /* Link back to owning channel */ | ||||||
|  |   ares_channel channel; | ||||||
|  |  | ||||||
|  |   /* Is this server broken? We mark connections as broken when a | ||||||
|  |    * request that is queued for sending times out. | ||||||
|  |    */ | ||||||
|  |   int is_broken; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /* State to represent a DNS query */ | ||||||
| struct query { | struct query { | ||||||
|   /* Query ID from qbuf, for faster lookup, and current timeout */ |   /* Query ID from qbuf, for faster lookup, and current timeout */ | ||||||
|   unsigned short qid; |   unsigned short qid; | ||||||
|   time_t timeout; |   struct timeval timeout; | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Links for the doubly-linked lists in which we insert a query. | ||||||
|  |    * These circular, doubly-linked lists that are hash-bucketed based | ||||||
|  |    * the attributes we care about, help making most important | ||||||
|  |    * operations O(1). | ||||||
|  |    */ | ||||||
|  |   struct list_node queries_by_qid;    /* hopefully in same cache line as qid */ | ||||||
|  |   struct list_node queries_by_timeout; | ||||||
|  |   struct list_node queries_to_server; | ||||||
|  |   struct list_node all_queries; | ||||||
|  |  | ||||||
|   /* Query buf with length at beginning, for TCP transmission */ |   /* Query buf with length at beginning, for TCP transmission */ | ||||||
|   unsigned char *tcpbuf; |   unsigned char *tcpbuf; | ||||||
| @@ -130,12 +176,16 @@ struct query { | |||||||
|   /* Query status */ |   /* Query status */ | ||||||
|   int try; |   int try; | ||||||
|   int server; |   int server; | ||||||
|   int *skip_server; |   struct query_server_info *server_info;   /* per-server state */ | ||||||
|   int using_tcp; |   int using_tcp; | ||||||
|   int error_status; |   int error_status; | ||||||
|  |   int timeouts; /* number of timeouts we saw for this request */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|   /* Next query in chain */ | /* Per-server state for a query */ | ||||||
|   struct query *next; | struct query_server_info { | ||||||
|  |   int skip_server;  /* should we skip server, due to errors, etc? */ | ||||||
|  |   int tcp_connection_generation;  /* into which TCP connection did we send? */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* An IP address pattern; matches an IP address X if X & mask == addr */ | /* An IP address pattern; matches an IP address X if X & mask == addr */ | ||||||
| @@ -168,11 +218,13 @@ typedef struct rc4_key | |||||||
| struct ares_channeldata { | struct ares_channeldata { | ||||||
|   /* Configuration data */ |   /* Configuration data */ | ||||||
|   int flags; |   int flags; | ||||||
|   int timeout; |   int timeout; /* in milliseconds */ | ||||||
|   int tries; |   int tries; | ||||||
|   int ndots; |   int ndots; | ||||||
|   int udp_port; |   int udp_port; | ||||||
|   int tcp_port; |   int tcp_port; | ||||||
|  |   int socket_send_buffer_size; | ||||||
|  |   int socket_receive_buffer_size; | ||||||
|   char **domains; |   char **domains; | ||||||
|   int ndomains; |   int ndomains; | ||||||
|   struct apattern *sortlist; |   struct apattern *sortlist; | ||||||
| @@ -188,19 +240,48 @@ struct ares_channeldata { | |||||||
|   /* key to use when generating new ids */ |   /* key to use when generating new ids */ | ||||||
|   rc4_key id_key; |   rc4_key id_key; | ||||||
|  |  | ||||||
|   /* Active queries */ |   /* Generation number to use for the next TCP socket open/close */ | ||||||
|   struct query *queries; |   int tcp_connection_generation; | ||||||
|  |  | ||||||
|  |   /* The time at which we last called process_timeouts(). Uses integer seconds | ||||||
|  |      just to draw the line somewhere. */ | ||||||
|  |   time_t last_timeout_processed; | ||||||
|  |  | ||||||
|  |   /* Circular, doubly-linked list of queries, bucketed various ways.... */ | ||||||
|  |   /* All active queries in a single list: */ | ||||||
|  |   struct list_node all_queries; | ||||||
|  |   /* Queries bucketed by qid, for quickly dispatching DNS responses: */ | ||||||
|  | #define ARES_QID_TABLE_SIZE 2048 | ||||||
|  |   struct list_node queries_by_qid[ARES_QID_TABLE_SIZE]; | ||||||
|  |   /* Queries bucketed by timeout, for quickly handling timeouts: */ | ||||||
|  | #define ARES_TIMEOUT_TABLE_SIZE 1024 | ||||||
|  |   struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE]; | ||||||
|  |  | ||||||
|   ares_sock_state_cb sock_state_cb; |   ares_sock_state_cb sock_state_cb; | ||||||
|   void *sock_state_cb_data; |   void *sock_state_cb_data; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /* return true if now is exactly check time or later */ | ||||||
|  | int ares__timedout(struct timeval *now, | ||||||
|  |                    struct timeval *check); | ||||||
|  | /* add the specific number of milliseconds to the time in the first argument */ | ||||||
|  | int ares__timeadd(struct timeval *now, | ||||||
|  |                   int millisecs); | ||||||
|  | /* return time offset between now and (future) check, in milliseconds */ | ||||||
|  | long ares__timeoffset(struct timeval *now, | ||||||
|  |                       struct timeval *check); | ||||||
| void ares__rc4(rc4_key* key,unsigned char *buffer_ptr, int buffer_len); | void ares__rc4(rc4_key* key,unsigned char *buffer_ptr, int buffer_len); | ||||||
| void ares__send_query(ares_channel channel, struct query *query, time_t now); | void ares__send_query(ares_channel channel, struct query *query, | ||||||
|  |                       struct timeval *now); | ||||||
| void ares__close_sockets(ares_channel channel, struct server_state *server); | void ares__close_sockets(ares_channel channel, struct server_state *server); | ||||||
| int ares__get_hostent(FILE *fp, int family, struct hostent **host); | int ares__get_hostent(FILE *fp, int family, struct hostent **host); | ||||||
| int ares__read_line(FILE *fp, char **buf, int *bufsize); | int ares__read_line(FILE *fp, char **buf, int *bufsize); | ||||||
|  | void ares__free_query(struct query *query); | ||||||
| short ares__generate_new_id(rc4_key* key); | short ares__generate_new_id(rc4_key* key); | ||||||
|  | struct timeval ares__tvnow(void); | ||||||
|  | #if 0 /* Not used */ | ||||||
|  | long ares__tvdiff(struct timeval t1, struct timeval t2); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #define ARES_SWAP_BYTE(a,b) \ | #define ARES_SWAP_BYTE(a,b) \ | ||||||
|   { unsigned char swapByte = *(a);  *(a) = *(b);  *(b) = swapByte; } |   { unsigned char swapByte = *(a);  *(a) = *(b);  *(b) = swapByte; } | ||||||
| @@ -220,4 +301,3 @@ short ares__generate_new_id(rc4_key* key); | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #endif /* __ARES_PRIVATE_H */ | #endif /* __ARES_PRIVATE_H */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright 1998 by the Massachusetts Institute of Technology. | /* Copyright 1998 by the Massachusetts Institute of Technology. | ||||||
|  |  * Copyright (C) 2004-2008 by Daniel Stenberg | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
| @@ -21,18 +22,35 @@ | |||||||
| #include "nameser.h" | #include "nameser.h" | ||||||
|  |  | ||||||
| #else | #else | ||||||
|  | #ifdef HAVE_SYS_SOCKET_H | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
|  | #endif | ||||||
| #ifdef HAVE_SYS_UIO_H | #ifdef HAVE_SYS_UIO_H | ||||||
| #include <sys/uio.h> | #include <sys/uio.h> | ||||||
| #endif | #endif | ||||||
| #include <netinet/in.h> | #ifdef HAVE_NETINET_IN_H | ||||||
|  | #include <netinet/in.h> /* <netinet/tcp.h> may need it */ | ||||||
|  | #endif | ||||||
|  | #ifdef HAVE_NETINET_TCP_H | ||||||
|  | #include <netinet/tcp.h> /* for TCP_NODELAY */ | ||||||
|  | #endif | ||||||
|  | #ifdef HAVE_NETDB_H | ||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
|  | #endif | ||||||
|  | #ifdef HAVE_ARPA_NAMESER_H | ||||||
| #include <arpa/nameser.h> | #include <arpa/nameser.h> | ||||||
|  | #endif | ||||||
| #ifdef HAVE_ARPA_NAMESER_COMPAT_H | #ifdef HAVE_ARPA_NAMESER_COMPAT_H | ||||||
| #include <arpa/nameser_compat.h> | #include <arpa/nameser_compat.h> | ||||||
| #endif | #endif | ||||||
|  | #ifdef HAVE_SYS_TIME_H | ||||||
|  | #include <sys/time.h> | ||||||
|  | #endif | ||||||
| #endif /* WIN32 && !WATT32 */ | #endif /* WIN32 && !WATT32 */ | ||||||
|  |  | ||||||
|  | #ifdef HAVE_STRINGS_H | ||||||
|  | #include <strings.h> | ||||||
|  | #endif | ||||||
| #ifdef HAVE_UNISTD_H | #ifdef HAVE_UNISTD_H | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #endif | #endif | ||||||
| @@ -43,6 +61,7 @@ | |||||||
| #include <sys/filio.h> | #include <sys/filio.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| @@ -56,35 +75,84 @@ | |||||||
|  |  | ||||||
| static int try_again(int errnum); | static int try_again(int errnum); | ||||||
| static void write_tcp_data(ares_channel channel, fd_set *write_fds, | static void write_tcp_data(ares_channel channel, fd_set *write_fds, | ||||||
|                            ares_socket_t write_fd, time_t now); |                            ares_socket_t write_fd, struct timeval *now); | ||||||
| static void read_tcp_data(ares_channel channel, fd_set *read_fds, | static void read_tcp_data(ares_channel channel, fd_set *read_fds, | ||||||
|                           ares_socket_t read_fd, time_t now); |                           ares_socket_t read_fd, struct timeval *now); | ||||||
| static void read_udp_packets(ares_channel channel, fd_set *read_fds, | static void read_udp_packets(ares_channel channel, fd_set *read_fds, | ||||||
|                              ares_socket_t read_fd, time_t now); |                              ares_socket_t read_fd, struct timeval *now); | ||||||
| static void process_timeouts(ares_channel channel, time_t now); | static void advance_tcp_send_queue(ares_channel channel, int whichserver, | ||||||
|  |                                    ssize_t num_bytes); | ||||||
|  | static void process_timeouts(ares_channel channel, struct timeval *now); | ||||||
|  | static void process_broken_connections(ares_channel channel, | ||||||
|  |                                        struct timeval *now); | ||||||
| static void process_answer(ares_channel channel, unsigned char *abuf, | static void process_answer(ares_channel channel, unsigned char *abuf, | ||||||
|                            int alen, int whichserver, int tcp, time_t now); |                            int alen, int whichserver, int tcp, | ||||||
| static void handle_error(ares_channel channel, int whichserver, time_t now); |                            struct timeval *now); | ||||||
| static struct query *next_server(ares_channel channel, struct query *query, time_t now); | static void handle_error(ares_channel channel, int whichserver, | ||||||
|  |                          struct timeval *now); | ||||||
|  | static void skip_server(ares_channel channel, struct query *query, | ||||||
|  |                         int whichserver); | ||||||
|  | static void next_server(ares_channel channel, struct query *query, | ||||||
|  |                         struct timeval *now); | ||||||
|  | static int configure_socket(int s, ares_channel channel); | ||||||
| static int open_tcp_socket(ares_channel channel, struct server_state *server); | static int open_tcp_socket(ares_channel channel, struct server_state *server); | ||||||
| static int open_udp_socket(ares_channel channel, struct server_state *server); | static int open_udp_socket(ares_channel channel, struct server_state *server); | ||||||
| static int same_questions(const unsigned char *qbuf, int qlen, | static int same_questions(const unsigned char *qbuf, int qlen, | ||||||
|                           const unsigned char *abuf, int alen); |                           const unsigned char *abuf, int alen); | ||||||
| static struct query *end_query(ares_channel channel, struct query *query, int status, | static void end_query(ares_channel channel, struct query *query, int status, | ||||||
|                       unsigned char *abuf, int alen); |                       unsigned char *abuf, int alen); | ||||||
|  |  | ||||||
|  | /* return true if now is exactly check time or later */ | ||||||
|  | int ares__timedout(struct timeval *now, | ||||||
|  |                    struct timeval *check) | ||||||
|  | { | ||||||
|  |   int secs = (now->tv_sec - check->tv_sec); | ||||||
|  |  | ||||||
|  |   if(secs > 0) | ||||||
|  |     return 1; /* yes, timed out */ | ||||||
|  |   if(secs < 0) | ||||||
|  |     return 0; /* nope, not timed out */ | ||||||
|  |  | ||||||
|  |   /* if the full seconds were identical, check the sub second parts */ | ||||||
|  |   return (now->tv_usec - check->tv_usec >= 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* add the specific number of milliseconds to the time in the first argument */ | ||||||
|  | int ares__timeadd(struct timeval *now, | ||||||
|  |                   int millisecs) | ||||||
|  | { | ||||||
|  |   now->tv_sec += millisecs/1000; | ||||||
|  |   now->tv_usec += (millisecs%1000)*1000; | ||||||
|  |  | ||||||
|  |   if(now->tv_usec >= 1000000) { | ||||||
|  |     ++(now->tv_sec); | ||||||
|  |     now->tv_usec -= 1000000; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* return time offset between now and (future) check, in milliseconds */ | ||||||
|  | long ares__timeoffset(struct timeval *now, | ||||||
|  |                       struct timeval *check) | ||||||
|  | { | ||||||
|  |   return (check->tv_sec - now->tv_sec)*1000 + | ||||||
|  |          (check->tv_usec - now->tv_usec)/1000; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* Something interesting happened on the wire, or there was a timeout. | /* Something interesting happened on the wire, or there was a timeout. | ||||||
|  * See what's up and respond accordingly. |  * See what's up and respond accordingly. | ||||||
|  */ |  */ | ||||||
| void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) | void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) | ||||||
| { | { | ||||||
|   time_t now; |   struct timeval now = ares__tvnow(); | ||||||
|  |  | ||||||
|   time(&now); |   write_tcp_data(channel, write_fds, ARES_SOCKET_BAD, &now); | ||||||
|   write_tcp_data(channel, write_fds, ARES_SOCKET_BAD, now); |   read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, &now); | ||||||
|   read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, now); |   read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, &now); | ||||||
|   read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, now); |   process_timeouts(channel, &now); | ||||||
|   process_timeouts(channel, now); |   process_broken_connections(channel, &now); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Something interesting happened on the wire, or there was a timeout. | /* Something interesting happened on the wire, or there was a timeout. | ||||||
| @@ -95,13 +163,12 @@ void ares_process_fd(ares_channel channel, | |||||||
|                                                file descriptors */ |                                                file descriptors */ | ||||||
|                      ares_socket_t write_fd) |                      ares_socket_t write_fd) | ||||||
| { | { | ||||||
|   time_t now; |   struct timeval now = ares__tvnow(); | ||||||
|  |  | ||||||
|   time(&now); |   write_tcp_data(channel, NULL, write_fd, &now); | ||||||
|   write_tcp_data(channel, NULL, write_fd, now); |   read_tcp_data(channel, NULL, read_fd, &now); | ||||||
|   read_tcp_data(channel, NULL, read_fd, now); |   read_udp_packets(channel, NULL, read_fd, &now); | ||||||
|   read_udp_packets(channel, NULL, read_fd, now); |   process_timeouts(channel, &now); | ||||||
|   process_timeouts(channel, now); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -136,7 +203,7 @@ static int try_again(int errnum) | |||||||
| static void write_tcp_data(ares_channel channel, | static void write_tcp_data(ares_channel channel, | ||||||
|                            fd_set *write_fds, |                            fd_set *write_fds, | ||||||
|                            ares_socket_t write_fd, |                            ares_socket_t write_fd, | ||||||
|                            time_t now) |                            struct timeval *now) | ||||||
| { | { | ||||||
|   struct server_state *server; |   struct server_state *server; | ||||||
|   struct send_request *sendreq; |   struct send_request *sendreq; | ||||||
| @@ -155,7 +222,8 @@ static void write_tcp_data(ares_channel channel, | |||||||
|       /* Make sure server has data to send and is selected in write_fds or |       /* Make sure server has data to send and is selected in write_fds or | ||||||
|          write_fd. */ |          write_fd. */ | ||||||
|       server = &channel->servers[i]; |       server = &channel->servers[i]; | ||||||
|       if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD) |       if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD || | ||||||
|  |           server->is_broken) | ||||||
|         continue; |         continue; | ||||||
|  |  | ||||||
|       if(write_fds) { |       if(write_fds) { | ||||||
| @@ -167,6 +235,14 @@ static void write_tcp_data(ares_channel channel, | |||||||
|           continue; |           continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       if(write_fds) | ||||||
|  |         /* If there's an error and we close this socket, then open | ||||||
|  |          * another with the same fd to talk to another server, then we | ||||||
|  |          * don't want to think that it was the new socket that was | ||||||
|  |          * ready. This is not disastrous, but is likely to result in | ||||||
|  |          * extra system calls and confusion. */ | ||||||
|  |         FD_CLR(server->tcp_socket, write_fds); | ||||||
|  |  | ||||||
|       /* Count the number of send queue items. */ |       /* Count the number of send queue items. */ | ||||||
|       n = 0; |       n = 0; | ||||||
|       for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) |       for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) | ||||||
| @@ -194,27 +270,7 @@ static void write_tcp_data(ares_channel channel, | |||||||
|             } |             } | ||||||
|  |  | ||||||
|           /* Advance the send queue by as many bytes as we sent. */ |           /* Advance the send queue by as many bytes as we sent. */ | ||||||
|           while (wcount) |           advance_tcp_send_queue(channel, i, wcount); | ||||||
|             { |  | ||||||
|               sendreq = server->qhead; |  | ||||||
|               if ((size_t)wcount >= sendreq->len) |  | ||||||
|                 { |  | ||||||
|                   wcount -= sendreq->len; |  | ||||||
|                   server->qhead = sendreq->next; |  | ||||||
|                   if (server->qhead == NULL) |  | ||||||
|                     { |  | ||||||
|                       SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0); |  | ||||||
|                       server->qtail = NULL; |  | ||||||
|                     } |  | ||||||
|                   free(sendreq); |  | ||||||
|                 } |  | ||||||
|               else |  | ||||||
|                 { |  | ||||||
|                   sendreq->data += wcount; |  | ||||||
|                   sendreq->len -= wcount; |  | ||||||
|                   break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|       else |       else | ||||||
|         { |         { | ||||||
| @@ -230,21 +286,38 @@ static void write_tcp_data(ares_channel channel, | |||||||
|             } |             } | ||||||
|  |  | ||||||
|           /* Advance the send queue by as many bytes as we sent. */ |           /* Advance the send queue by as many bytes as we sent. */ | ||||||
|           if ((size_t)scount == sendreq->len) |           advance_tcp_send_queue(channel, i, scount); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Consume the given number of bytes from the head of the TCP send queue. */ | ||||||
|  | static void advance_tcp_send_queue(ares_channel channel, int whichserver, | ||||||
|  |                                    ssize_t num_bytes) | ||||||
|  | { | ||||||
|  |   struct send_request *sendreq; | ||||||
|  |   struct server_state *server = &channel->servers[whichserver]; | ||||||
|  |   while (num_bytes > 0) | ||||||
|     { |     { | ||||||
|  |       sendreq = server->qhead; | ||||||
|  |       if ((size_t)num_bytes >= sendreq->len) | ||||||
|  |        { | ||||||
|  |          num_bytes -= sendreq->len; | ||||||
|          server->qhead = sendreq->next; |          server->qhead = sendreq->next; | ||||||
|          if (server->qhead == NULL) |          if (server->qhead == NULL) | ||||||
|            { |            { | ||||||
|              SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0); |              SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0); | ||||||
|              server->qtail = NULL; |              server->qtail = NULL; | ||||||
|            } |            } | ||||||
|  |          if (sendreq->data_storage != NULL) | ||||||
|  |            free(sendreq->data_storage); | ||||||
|          free(sendreq); |          free(sendreq); | ||||||
|        } |        } | ||||||
|       else |       else | ||||||
|        { |        { | ||||||
|               sendreq->data += scount; |          sendreq->data += num_bytes; | ||||||
|               sendreq->len -= scount; |          sendreq->len -= num_bytes; | ||||||
|             } |          num_bytes = 0; | ||||||
|        } |        } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -254,7 +327,7 @@ static void write_tcp_data(ares_channel channel, | |||||||
|  * a packet if we finish reading one. |  * a packet if we finish reading one. | ||||||
|  */ |  */ | ||||||
| static void read_tcp_data(ares_channel channel, fd_set *read_fds, | static void read_tcp_data(ares_channel channel, fd_set *read_fds, | ||||||
|                           ares_socket_t read_fd, time_t now) |                           ares_socket_t read_fd, struct timeval *now) | ||||||
| { | { | ||||||
|   struct server_state *server; |   struct server_state *server; | ||||||
|   int i; |   int i; | ||||||
| @@ -268,7 +341,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, | |||||||
|     { |     { | ||||||
|       /* Make sure the server has a socket and is selected in read_fds. */ |       /* Make sure the server has a socket and is selected in read_fds. */ | ||||||
|       server = &channel->servers[i]; |       server = &channel->servers[i]; | ||||||
|       if (server->tcp_socket == ARES_SOCKET_BAD) |       if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken) | ||||||
|         continue; |         continue; | ||||||
|  |  | ||||||
|       if(read_fds) { |       if(read_fds) { | ||||||
| @@ -280,6 +353,14 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, | |||||||
|           continue; |           continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       if(read_fds) | ||||||
|  |         /* If there's an error and we close this socket, then open | ||||||
|  |          * another with the same fd to talk to another server, then we | ||||||
|  |          * don't want to think that it was the new socket that was | ||||||
|  |          * ready. This is not disastrous, but is likely to result in | ||||||
|  |          * extra system calls and confusion. */ | ||||||
|  |         FD_CLR(server->tcp_socket, read_fds); | ||||||
|  |  | ||||||
|       if (server->tcp_lenbuf_pos != 2) |       if (server->tcp_lenbuf_pos != 2) | ||||||
|         { |         { | ||||||
|           /* We haven't yet read a length word, so read that (or |           /* We haven't yet read a length word, so read that (or | ||||||
| @@ -342,12 +423,16 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, | |||||||
|  |  | ||||||
| /* If any UDP sockets select true for reading, process them. */ | /* If any UDP sockets select true for reading, process them. */ | ||||||
| static void read_udp_packets(ares_channel channel, fd_set *read_fds, | static void read_udp_packets(ares_channel channel, fd_set *read_fds, | ||||||
|                              ares_socket_t read_fd, time_t now) |                              ares_socket_t read_fd, struct timeval *now) | ||||||
| { | { | ||||||
|   struct server_state *server; |   struct server_state *server; | ||||||
|   int i; |   int i; | ||||||
|   ssize_t count; |   ssize_t count; | ||||||
|   unsigned char buf[PACKETSZ + 1]; |   unsigned char buf[PACKETSZ + 1]; | ||||||
|  | #ifdef HAVE_RECVFROM | ||||||
|  |   struct sockaddr_in from; | ||||||
|  |   socklen_t fromlen; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   if(!read_fds && (read_fd == ARES_SOCKET_BAD)) |   if(!read_fds && (read_fd == ARES_SOCKET_BAD)) | ||||||
|     /* no possible action */ |     /* no possible action */ | ||||||
| @@ -358,7 +443,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, | |||||||
|       /* Make sure the server has a socket and is selected in read_fds. */ |       /* Make sure the server has a socket and is selected in read_fds. */ | ||||||
|       server = &channel->servers[i]; |       server = &channel->servers[i]; | ||||||
|  |  | ||||||
|       if (server->udp_socket == ARES_SOCKET_BAD) |       if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken) | ||||||
|         continue; |         continue; | ||||||
|  |  | ||||||
|       if(read_fds) { |       if(read_fds) { | ||||||
| @@ -370,38 +455,83 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, | |||||||
|           continue; |           continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       if(read_fds) | ||||||
|  |         /* If there's an error and we close this socket, then open | ||||||
|  |          * another with the same fd to talk to another server, then we | ||||||
|  |          * don't want to think that it was the new socket that was | ||||||
|  |          * ready. This is not disastrous, but is likely to result in | ||||||
|  |          * extra system calls and confusion. */ | ||||||
|  |         FD_CLR(server->udp_socket, read_fds); | ||||||
|  |  | ||||||
|  |       /* To reduce event loop overhead, read and process as many | ||||||
|  |        * packets as we can. */ | ||||||
|  |       do { | ||||||
|  | #ifdef HAVE_RECVFROM | ||||||
|  |         fromlen = sizeof(from); | ||||||
|  |         count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf), | ||||||
|  |                                   0, (struct sockaddr *)&from, &fromlen); | ||||||
|  | #else | ||||||
|         count = sread(server->udp_socket, buf, sizeof(buf)); |         count = sread(server->udp_socket, buf, sizeof(buf)); | ||||||
|  | #endif | ||||||
|         if (count == -1 && try_again(SOCKERRNO)) |         if (count == -1 && try_again(SOCKERRNO)) | ||||||
|           continue; |           continue; | ||||||
|         else if (count <= 0) |         else if (count <= 0) | ||||||
|           handle_error(channel, i, now); |           handle_error(channel, i, now); | ||||||
|  | #ifdef HAVE_RECVFROM | ||||||
|  |         else if (from.sin_addr.s_addr != server->addr.s_addr) | ||||||
|  |           /* Address response came from did not match the address | ||||||
|  |            * we sent the request to.  Someone may be attempting | ||||||
|  |            * to perform a cache poisoning attack */ | ||||||
|  |           break; | ||||||
|  | #endif | ||||||
|  |         else | ||||||
|           process_answer(channel, buf, (int)count, i, 0, now); |           process_answer(channel, buf, (int)count, i, 0, now); | ||||||
|  |        } while (count > 0); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* If any queries have timed out, note the timeout and move them on. */ | /* If any queries have timed out, note the timeout and move them on. */ | ||||||
| static void process_timeouts(ares_channel channel, time_t now) | static void process_timeouts(ares_channel channel, struct timeval *now) | ||||||
| { | { | ||||||
|   struct query *query, *next; |   time_t t;  /* the time of the timeouts we're processing */ | ||||||
|  |   struct query *query; | ||||||
|  |   struct list_node* list_head; | ||||||
|  |   struct list_node* list_node; | ||||||
|  |  | ||||||
|   for (query = channel->queries; query; query = next) |   /* Process all the timeouts that have fired since the last time we | ||||||
|  |    * processed timeouts. If things are going well, then we'll have | ||||||
|  |    * hundreds/thousands of queries that fall into future buckets, and | ||||||
|  |    * only a handful of requests that fall into the "now" bucket, so | ||||||
|  |    * this should be quite quick. | ||||||
|  |    */ | ||||||
|  |   for (t = channel->last_timeout_processed; t <= now->tv_sec; t++) | ||||||
|     { |     { | ||||||
|       next = query->next; |       list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]); | ||||||
|       if (query->timeout != 0 && now >= query->timeout) |       for (list_node = list_head->next; list_node != list_head; ) | ||||||
|  |         { | ||||||
|  |           query = list_node->data; | ||||||
|  |           list_node = list_node->next;  /* in case the query gets deleted */ | ||||||
|  |           if (query->timeout.tv_sec && ares__timedout(now, &query->timeout)) | ||||||
|             { |             { | ||||||
|               query->error_status = ARES_ETIMEOUT; |               query->error_status = ARES_ETIMEOUT; | ||||||
|           next = next_server(channel, query, now); |               ++query->timeouts; | ||||||
|  |               next_server(channel, query, now); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |      } | ||||||
|  |   channel->last_timeout_processed = now->tv_sec; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Handle an answer from a server. */ | /* Handle an answer from a server. */ | ||||||
| static void process_answer(ares_channel channel, unsigned char *abuf, | static void process_answer(ares_channel channel, unsigned char *abuf, | ||||||
|                            int alen, int whichserver, int tcp, time_t now) |                            int alen, int whichserver, int tcp, | ||||||
|  |                            struct timeval *now) | ||||||
| { | { | ||||||
|   int id, tc, rcode; |   int tc, rcode; | ||||||
|  |   unsigned short id; | ||||||
|   struct query *query; |   struct query *query; | ||||||
|  |   struct list_node* list_head; | ||||||
|  |   struct list_node* list_node; | ||||||
|  |  | ||||||
|   /* If there's no room in the answer for a header, we can't do much |   /* If there's no room in the answer for a header, we can't do much | ||||||
|    * with it. */ |    * with it. */ | ||||||
| @@ -413,12 +543,25 @@ static void process_answer(ares_channel channel, unsigned char *abuf, | |||||||
|   tc = DNS_HEADER_TC(abuf); |   tc = DNS_HEADER_TC(abuf); | ||||||
|   rcode = DNS_HEADER_RCODE(abuf); |   rcode = DNS_HEADER_RCODE(abuf); | ||||||
|  |  | ||||||
|   /* Find the query corresponding to this packet. */ |   /* Find the query corresponding to this packet. The queries are | ||||||
|   for (query = channel->queries; query; query = query->next) |    * hashed/bucketed by query id, so this lookup should be quick. | ||||||
|  |    * Note that both the query id and the questions must be the same; | ||||||
|  |    * when the query id wraps around we can have multiple outstanding | ||||||
|  |    * queries with the same query id, so we need to check both the id and | ||||||
|  |    * question. | ||||||
|  |    */ | ||||||
|  |   query = NULL; | ||||||
|  |   list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]); | ||||||
|  |   for (list_node = list_head->next; list_node != list_head; | ||||||
|  |        list_node = list_node->next) | ||||||
|     { |     { | ||||||
|       if (query->qid == id) |       struct query *q = list_node->data; | ||||||
|  |       if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen)) | ||||||
|  |         { | ||||||
|  |           query = q; | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|   if (!query) |   if (!query) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
| @@ -449,13 +592,7 @@ static void process_answer(ares_channel channel, unsigned char *abuf, | |||||||
|     { |     { | ||||||
|       if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED) |       if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED) | ||||||
|         { |         { | ||||||
|           query->skip_server[whichserver] = 1; |           skip_server(channel, query, whichserver); | ||||||
|           if (query->server == whichserver) |  | ||||||
|             next_server(channel, query, now); |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
|       if (!same_questions(query->qbuf, query->qlen, abuf, alen)) |  | ||||||
|         { |  | ||||||
|           if (query->server == whichserver) |           if (query->server == whichserver) | ||||||
|             next_server(channel, query, now); |             next_server(channel, query, now); | ||||||
|           return; |           return; | ||||||
| @@ -465,29 +602,75 @@ static void process_answer(ares_channel channel, unsigned char *abuf, | |||||||
|   end_query(channel, query, ARES_SUCCESS, abuf, alen); |   end_query(channel, query, ARES_SUCCESS, abuf, alen); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void handle_error(ares_channel channel, int whichserver, time_t now) | /* Close all the connections that are no longer usable. */ | ||||||
|  | static void process_broken_connections(ares_channel channel, | ||||||
|  |                                        struct timeval *now) | ||||||
| { | { | ||||||
|   struct query *query, *next; |   int i; | ||||||
|  |   for (i = 0; i < channel->nservers; i++) | ||||||
|   /* Reset communications with this server. */ |  | ||||||
|   ares__close_sockets(channel, &channel->servers[whichserver]); |  | ||||||
|  |  | ||||||
|   /* Tell all queries talking to this server to move on and not try |  | ||||||
|    * this server again. |  | ||||||
|    */ |  | ||||||
|  |  | ||||||
|   for (query = channel->queries; query; query = next) |  | ||||||
|     { |     { | ||||||
|       next = query->next; |       struct server_state *server = &channel->servers[i]; | ||||||
|       if (query->server == whichserver) |       if (server->is_broken) | ||||||
|         { |         { | ||||||
|           query->skip_server[whichserver] = 1; |           handle_error(channel, i, now); | ||||||
|           next = next_server(channel, query, now); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static struct query *next_server(ares_channel channel, struct query *query, time_t now) | static void handle_error(ares_channel channel, int whichserver, | ||||||
|  |                          struct timeval *now) | ||||||
|  | { | ||||||
|  |   struct server_state *server; | ||||||
|  |   struct query *query; | ||||||
|  |   struct list_node list_head; | ||||||
|  |   struct list_node* list_node; | ||||||
|  |  | ||||||
|  |   server = &channel->servers[whichserver]; | ||||||
|  |  | ||||||
|  |   /* Reset communications with this server. */ | ||||||
|  |   ares__close_sockets(channel, server); | ||||||
|  |  | ||||||
|  |   /* Tell all queries talking to this server to move on and not try | ||||||
|  |    * this server again. We steal the current list of queries that were | ||||||
|  |    * in-flight to this server, since when we call next_server this can | ||||||
|  |    * cause the queries to be re-sent to this server, which will | ||||||
|  |    * re-insert these queries in that same server->queries_to_server | ||||||
|  |    * list. | ||||||
|  |    */ | ||||||
|  |   ares__init_list_head(&list_head); | ||||||
|  |   ares__swap_lists(&list_head, &(server->queries_to_server)); | ||||||
|  |   for (list_node = list_head.next; list_node != &list_head; ) | ||||||
|  |     { | ||||||
|  |       query = list_node->data; | ||||||
|  |       list_node = list_node->next;  /* in case the query gets deleted */ | ||||||
|  |       assert(query->server == whichserver); | ||||||
|  |       skip_server(channel, query, whichserver); | ||||||
|  |       next_server(channel, query, now); | ||||||
|  |     } | ||||||
|  |   /* Each query should have removed itself from our temporary list as | ||||||
|  |    * it re-sent itself or finished up... | ||||||
|  |    */ | ||||||
|  |   assert(ares__is_list_empty(&list_head)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void skip_server(ares_channel channel, struct query *query, | ||||||
|  |                         int whichserver) { | ||||||
|  |   /* The given server gave us problems with this query, so if we have | ||||||
|  |    * the luxury of using other servers, then let's skip the | ||||||
|  |    * potentially broken server and just use the others. If we only | ||||||
|  |    * have one server and we need to retry then we should just go ahead | ||||||
|  |    * and re-use that server, since it's our only hope; perhaps we | ||||||
|  |    * just got unlucky, and retrying will work (eg, the server timed | ||||||
|  |    * out our TCP connection just as we were sending another request). | ||||||
|  |    */ | ||||||
|  |   if (channel->nservers > 1) | ||||||
|  |     { | ||||||
|  |       query->server_info[whichserver].skip_server = 1; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void next_server(ares_channel channel, struct query *query, | ||||||
|  |                         struct timeval *now) | ||||||
| { | { | ||||||
|   /* Advance to the next server or try. */ |   /* Advance to the next server or try. */ | ||||||
|   query->server++; |   query->server++; | ||||||
| @@ -495,22 +678,37 @@ static struct query *next_server(ares_channel channel, struct query *query, time | |||||||
|     { |     { | ||||||
|       for (; query->server < channel->nservers; query->server++) |       for (; query->server < channel->nservers; query->server++) | ||||||
|         { |         { | ||||||
|           if (!query->skip_server[query->server]) |           struct server_state *server = &channel->servers[query->server]; | ||||||
|  |           /* We don't want to use this server if (1) we decided this | ||||||
|  |            * connection is broken, and thus about to be closed, (2) | ||||||
|  |            * we've decided to skip this server because of earlier | ||||||
|  |            * errors we encountered, or (3) we already sent this query | ||||||
|  |            * over this exact connection. | ||||||
|  |            */ | ||||||
|  |           if (!server->is_broken && | ||||||
|  |                !query->server_info[query->server].skip_server && | ||||||
|  |                !(query->using_tcp && | ||||||
|  |                  (query->server_info[query->server].tcp_connection_generation == | ||||||
|  |                   server->tcp_connection_generation))) | ||||||
|             { |             { | ||||||
|                ares__send_query(channel, query, now); |                ares__send_query(channel, query, now); | ||||||
|               return (query->next); |                return; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|       query->server = 0; |       query->server = 0; | ||||||
|  |  | ||||||
|       /* Only one try if we're using TCP. */ |       /* You might think that with TCP we only need one try. However, | ||||||
|       if (query->using_tcp) |        * even when using TCP, servers can time-out our connection just | ||||||
|         break; |        * as we're sending a request, or close our connection because | ||||||
|  |        * they die, or never send us a reply because they get wedged or | ||||||
|  |        * tickle a bug that drops our request. | ||||||
|  |        */ | ||||||
|     } |     } | ||||||
|   return end_query(channel, query, query->error_status, NULL, 0); |   end_query(channel, query, query->error_status, NULL, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ares__send_query(ares_channel channel, struct query *query, time_t now) | void ares__send_query(ares_channel channel, struct query *query, | ||||||
|  |                       struct timeval *now) | ||||||
| { | { | ||||||
|   struct send_request *sendreq; |   struct send_request *sendreq; | ||||||
|   struct server_state *server; |   struct server_state *server; | ||||||
| @@ -525,7 +723,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) | |||||||
|         { |         { | ||||||
|           if (open_tcp_socket(channel, server) == -1) |           if (open_tcp_socket(channel, server) == -1) | ||||||
|             { |             { | ||||||
|               query->skip_server[query->server] = 1; |               skip_server(channel, query, query->server); | ||||||
|               next_server(channel, query, now); |               next_server(channel, query, now); | ||||||
|               return; |               return; | ||||||
|             } |             } | ||||||
| @@ -536,8 +734,16 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) | |||||||
|         end_query(channel, query, ARES_ENOMEM, NULL, 0); |         end_query(channel, query, ARES_ENOMEM, NULL, 0); | ||||||
|           return; |           return; | ||||||
|         } |         } | ||||||
|  |       /* To make the common case fast, we avoid copies by using the | ||||||
|  |        * query's tcpbuf for as long as the query is alive. In the rare | ||||||
|  |        * case where the query ends while it's queued for transmission, | ||||||
|  |        * then we give the sendreq its own copy of the request packet | ||||||
|  |        * and put it in sendreq->data_storage. | ||||||
|  |        */ | ||||||
|  |       sendreq->data_storage = NULL; | ||||||
|       sendreq->data = query->tcpbuf; |       sendreq->data = query->tcpbuf; | ||||||
|       sendreq->len = query->tcplen; |       sendreq->len = query->tcplen; | ||||||
|  |       sendreq->owner_query = query; | ||||||
|       sendreq->next = NULL; |       sendreq->next = NULL; | ||||||
|       if (server->qtail) |       if (server->qtail) | ||||||
|         server->qtail->next = sendreq; |         server->qtail->next = sendreq; | ||||||
| @@ -547,7 +753,8 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) | |||||||
|           server->qhead = sendreq; |           server->qhead = sendreq; | ||||||
|         } |         } | ||||||
|       server->qtail = sendreq; |       server->qtail = sendreq; | ||||||
|       query->timeout = 0; |       query->server_info[query->server].tcp_connection_generation = | ||||||
|  |         server->tcp_connection_generation; | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
| @@ -555,7 +762,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) | |||||||
|         { |         { | ||||||
|           if (open_udp_socket(channel, server) == -1) |           if (open_udp_socket(channel, server) == -1) | ||||||
|             { |             { | ||||||
|               query->skip_server[query->server] = 1; |               skip_server(channel, query, query->server); | ||||||
|               next_server(channel, query, now); |               next_server(channel, query, now); | ||||||
|               return; |               return; | ||||||
|             } |             } | ||||||
| @@ -563,21 +770,37 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now) | |||||||
|       if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1) |       if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1) | ||||||
|         { |         { | ||||||
|           /* FIXME: Handle EAGAIN here since it likely can happen. */ |           /* FIXME: Handle EAGAIN here since it likely can happen. */ | ||||||
|           query->skip_server[query->server] = 1; |           skip_server(channel, query, query->server); | ||||||
|           next_server(channel, query, now); |           next_server(channel, query, now); | ||||||
|           return; |           return; | ||||||
|         } |         } | ||||||
|       query->timeout = now |  | ||||||
|           + ((query->try == 0) ? channel->timeout |  | ||||||
|              : channel->timeout << query->try / channel->nservers); |  | ||||||
|     } |     } | ||||||
|  |     query->timeout = *now; | ||||||
|  |     ares__timeadd(&query->timeout, | ||||||
|  |                   (query->try == 0) ? channel->timeout | ||||||
|  |                   : channel->timeout << query->try / channel->nservers); | ||||||
|  |     /* Keep track of queries bucketed by timeout, so we can process | ||||||
|  |      * timeout events quickly. | ||||||
|  |      */ | ||||||
|  |     ares__remove_from_list(&(query->queries_by_timeout)); | ||||||
|  |     ares__insert_in_list( | ||||||
|  |         &(query->queries_by_timeout), | ||||||
|  |         &(channel->queries_by_timeout[query->timeout.tv_sec % | ||||||
|  |                                       ARES_TIMEOUT_TABLE_SIZE])); | ||||||
|  |  | ||||||
|  |     /* Keep track of queries bucketed by server, so we can process server | ||||||
|  |      * errors quickly. | ||||||
|  |      */ | ||||||
|  |     ares__remove_from_list(&(query->queries_to_server)); | ||||||
|  |     ares__insert_in_list(&(query->queries_to_server), | ||||||
|  |                          &(server->queries_to_server)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * nonblock() set the given socket to either blocking or non-blocking mode |  * setsocknonblock sets the given socket to either blocking or non-blocking mode | ||||||
|  * based on the 'nonblock' boolean argument. This function is highly portable. |  * based on the 'nonblock' boolean argument. This function is highly portable. | ||||||
|  */ |  */ | ||||||
| static int nonblock(ares_socket_t sockfd,    /* operate on this */ | static int setsocknonblock(ares_socket_t sockfd,    /* operate on this */ | ||||||
|                     int nonblock   /* TRUE or FALSE */) |                     int nonblock   /* TRUE or FALSE */) | ||||||
| { | { | ||||||
| #undef SETBLOCK | #undef SETBLOCK | ||||||
| @@ -645,9 +868,36 @@ static int nonblock(ares_socket_t sockfd,    /* operate on this */ | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int configure_socket(int s, ares_channel channel) | ||||||
|  | { | ||||||
|  |   setsocknonblock(s, TRUE); | ||||||
|  |  | ||||||
|  | #if defined(FD_CLOEXEC) && !defined(MSDOS) | ||||||
|  |   /* Configure the socket fd as close-on-exec. */ | ||||||
|  |   if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) | ||||||
|  |     return -1; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   /* Set the socket's send and receive buffer sizes. */ | ||||||
|  |   if ((channel->socket_send_buffer_size > 0) && | ||||||
|  |       setsockopt(s, SOL_SOCKET, SO_SNDBUF, | ||||||
|  |                  (void *)&channel->socket_send_buffer_size, | ||||||
|  |                  sizeof(channel->socket_send_buffer_size)) == -1) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|  |   if ((channel->socket_receive_buffer_size > 0) && | ||||||
|  |       setsockopt(s, SOL_SOCKET, SO_RCVBUF, | ||||||
|  |                  (void *)&channel->socket_receive_buffer_size, | ||||||
|  |                  sizeof(channel->socket_receive_buffer_size)) == -1) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  |  } | ||||||
|  |  | ||||||
| static int open_tcp_socket(ares_channel channel, struct server_state *server) | static int open_tcp_socket(ares_channel channel, struct server_state *server) | ||||||
| { | { | ||||||
|   ares_socket_t s; |   ares_socket_t s; | ||||||
|  |   int opt; | ||||||
|   struct sockaddr_in sockin; |   struct sockaddr_in sockin; | ||||||
|  |  | ||||||
|   /* Acquire a socket. */ |   /* Acquire a socket. */ | ||||||
| @@ -655,8 +905,26 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) | |||||||
|   if (s == ARES_SOCKET_BAD) |   if (s == ARES_SOCKET_BAD) | ||||||
|     return -1; |     return -1; | ||||||
|  |  | ||||||
|   /* Set the socket non-blocking. */ |   /* Configure it. */ | ||||||
|   nonblock(s, TRUE); |   if (configure_socket(s, channel) < 0) | ||||||
|  |     { | ||||||
|  |        close(s); | ||||||
|  |        return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in | ||||||
|  |    * configure_socket). In general, in DNS lookups we're pretty much interested | ||||||
|  |    * in firing off a single request and then waiting for a reply, so batching | ||||||
|  |    * isn't very interesting in general. | ||||||
|  |    */ | ||||||
|  |   opt = 1; | ||||||
|  |   if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, | ||||||
|  |                  (void *)&opt, sizeof(opt)) == -1) | ||||||
|  |     { | ||||||
|  |        close(s); | ||||||
|  |        return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   /* Connect to the server. */ |   /* Connect to the server. */ | ||||||
|   memset(&sockin, 0, sizeof(sockin)); |   memset(&sockin, 0, sizeof(sockin)); | ||||||
| @@ -675,6 +943,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) | |||||||
|   SOCK_STATE_CALLBACK(channel, s, 1, 0); |   SOCK_STATE_CALLBACK(channel, s, 1, 0); | ||||||
|   server->tcp_buffer_pos = 0; |   server->tcp_buffer_pos = 0; | ||||||
|   server->tcp_socket = s; |   server->tcp_socket = s; | ||||||
|  |   server->tcp_connection_generation = ++channel->tcp_connection_generation; | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -689,7 +958,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) | |||||||
|     return -1; |     return -1; | ||||||
|  |  | ||||||
|   /* Set the socket non-blocking. */ |   /* Set the socket non-blocking. */ | ||||||
|   nonblock(s, TRUE); |   if (configure_socket(s, channel) < 0) | ||||||
|  |     { | ||||||
|  |        close(s); | ||||||
|  |        return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   /* Connect to the server. */ |   /* Connect to the server. */ | ||||||
|   memset(&sockin, 0, sizeof(sockin)); |   memset(&sockin, 0, sizeof(sockin)); | ||||||
| @@ -787,34 +1060,92 @@ static int same_questions(const unsigned char *qbuf, int qlen, | |||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static struct query *end_query (ares_channel channel, struct query *query, int status, | static void end_query (ares_channel channel, struct query *query, int status, | ||||||
|                        unsigned char *abuf, int alen) |                        unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   struct query **q, *next; |  | ||||||
|   int i; |   int i; | ||||||
|  |  | ||||||
|   query->callback(query->arg, status, abuf, alen); |   /* First we check to see if this query ended while one of our send | ||||||
|   for (q = &channel->queries; *q; q = &(*q)->next) |    * queues still has pointers to it. | ||||||
|  |    */ | ||||||
|  |   for (i = 0; i < channel->nservers; i++) | ||||||
|     { |     { | ||||||
|       if (*q == query) |       struct server_state *server = &channel->servers[i]; | ||||||
|         break; |       struct send_request *sendreq; | ||||||
|  |       for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) | ||||||
|  |         if (sendreq->owner_query == query) | ||||||
|  |           { | ||||||
|  |             sendreq->owner_query = NULL; | ||||||
|  |             assert(sendreq->data_storage == NULL); | ||||||
|  |             if (status == ARES_SUCCESS) | ||||||
|  |               { | ||||||
|  |                 /* We got a reply for this query, but this queued | ||||||
|  |                  * sendreq points into this soon-to-be-gone query's | ||||||
|  |                  * tcpbuf. Probably this means we timed out and queued | ||||||
|  |                  * the query for retransmission, then received a | ||||||
|  |                  * response before actually retransmitting. This is | ||||||
|  |                  * perfectly fine, so we want to keep the connection | ||||||
|  |                  * running smoothly if we can. But in the worst case | ||||||
|  |                  * we may have sent only some prefix of the query, | ||||||
|  |                  * with some suffix of the query left to send. Also, | ||||||
|  |                  * the buffer may be queued on multiple queues. To | ||||||
|  |                  * prevent dangling pointers to the query's tcpbuf and | ||||||
|  |                  * handle these cases, we just give such sendreqs | ||||||
|  |                  * their own copy of the query packet. | ||||||
|  |                  */ | ||||||
|  |                sendreq->data_storage = malloc(sendreq->len); | ||||||
|  |                if (sendreq->data_storage != NULL) | ||||||
|  |                  { | ||||||
|  |                    memcpy(sendreq->data_storage, sendreq->data, sendreq->len); | ||||||
|  |                    sendreq->data = sendreq->data_storage; | ||||||
|                  } |                  } | ||||||
|   *q = query->next; |               } | ||||||
|   if (*q) |             if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL)) | ||||||
|     next = (*q)->next; |               { | ||||||
|   else |                 /* We encountered an error (probably a timeout, | ||||||
|     next = NULL; |                  * suggesting the DNS server we're talking to is | ||||||
|   free(query->tcpbuf); |                  * probably unreachable, wedged, or severely | ||||||
|   free(query->skip_server); |                  * overloaded) or we couldn't copy the request, so | ||||||
|   free(query); |                  * mark the connection as broken. When we get to | ||||||
|  |                  * process_broken_connections() we'll close the | ||||||
|  |                  * connection and try to re-send requests to another | ||||||
|  |                  * server. | ||||||
|  |                  */ | ||||||
|  |                server->is_broken = 1; | ||||||
|  |                /* Just to be paranoid, zero out this sendreq... */ | ||||||
|  |                sendreq->data = NULL; | ||||||
|  |                sendreq->len = 0; | ||||||
|  |              } | ||||||
|  |           } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* Invoke the callback */ | ||||||
|  |   query->callback(query->arg, status, query->timeouts, abuf, alen); | ||||||
|  |   ares__free_query(query); | ||||||
|  |  | ||||||
|   /* Simple cleanup policy: if no queries are remaining, close all |   /* Simple cleanup policy: if no queries are remaining, close all | ||||||
|    * network sockets unless STAYOPEN is set. |    * network sockets unless STAYOPEN is set. | ||||||
|    */ |    */ | ||||||
|   if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN)) |   if (!(channel->flags & ARES_FLAG_STAYOPEN) && | ||||||
|  |       ares__is_list_empty(&(channel->all_queries))) | ||||||
|     { |     { | ||||||
|       for (i = 0; i < channel->nservers; i++) |       for (i = 0; i < channel->nservers; i++) | ||||||
|         ares__close_sockets(channel, &channel->servers[i]); |         ares__close_sockets(channel, &channel->servers[i]); | ||||||
|     } |     } | ||||||
|   return (next); | } | ||||||
|  |  | ||||||
|  | void ares__free_query(struct query *query) | ||||||
|  | { | ||||||
|  |   /* Remove the query from all the lists in which it is linked */ | ||||||
|  |   ares__remove_from_list(&(query->queries_by_qid)); | ||||||
|  |   ares__remove_from_list(&(query->queries_by_timeout)); | ||||||
|  |   ares__remove_from_list(&(query->queries_to_server)); | ||||||
|  |   ares__remove_from_list(&(query->all_queries)); | ||||||
|  |   /* Zero out some important stuff, to help catch bugs */ | ||||||
|  |   query->callback = NULL; | ||||||
|  |   query->arg = NULL; | ||||||
|  |   /* Deallocate the memory associated with the query */ | ||||||
|  |   free(query->tcpbuf); | ||||||
|  |   free(query->server_info); | ||||||
|  |   free(query); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ ares_query \- Initiate a single-question DNS query | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, | .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, | ||||||
| .B	unsigned char *\fIabuf\fP, int \fIalen\fP) | .B	int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP) | ||||||
| .PP | .PP | ||||||
| .B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP, | .B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP, | ||||||
| .B 	int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, | .B 	int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, | ||||||
| @@ -124,6 +124,11 @@ The name service channel | |||||||
| .I channel | .I channel | ||||||
| is being destroyed; the query will not be completed. | is being destroyed; the query will not be completed. | ||||||
| .PP | .PP | ||||||
|  | The callback argument | ||||||
|  | .I timeouts | ||||||
|  | reports how many times a query timed out during the execution of the | ||||||
|  | given request. | ||||||
|  | .PP | ||||||
| If the query completed (even if there was something wrong with it, as | If the query completed (even if there was something wrong with it, as | ||||||
| indicated by some of the above error codes), the callback argument | indicated by some of the above error codes), the callback argument | ||||||
| .I abuf | .I abuf | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ struct qquery { | |||||||
|   void *arg; |   void *arg; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void qcallback(void *arg, int status, unsigned char *abuf, int alen); | static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); | ||||||
|  |  | ||||||
| void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) | void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) | ||||||
| { | { | ||||||
| @@ -53,13 +53,13 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) | |||||||
|   state = &key->state[0]; |   state = &key->state[0]; | ||||||
|   for(counter = 0; counter < buffer_len; counter ++) |   for(counter = 0; counter < buffer_len; counter ++) | ||||||
|   { |   { | ||||||
| 	x = (x + 1) % 256; |     x = (unsigned char)((x + 1) % 256); | ||||||
| 	y = (state[x] + y) % 256; |     y = (unsigned char)((state[x] + y) % 256); | ||||||
|     ARES_SWAP_BYTE(&state[x], &state[y]); |     ARES_SWAP_BYTE(&state[x], &state[y]); | ||||||
|  |  | ||||||
| 	xorIndex = (state[x] + state[y]) % 256; |     xorIndex = (unsigned char)((state[x] + state[y]) % 256); | ||||||
|  |  | ||||||
| 	buffer_ptr[counter] ^= state[xorIndex]; |     buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]); | ||||||
|   } |   } | ||||||
|   key->x = x; |   key->x = x; | ||||||
|   key->y = y; |   key->y = y; | ||||||
| @@ -67,13 +67,17 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) | |||||||
|  |  | ||||||
| static struct query* find_query_by_id(ares_channel channel, int id) | static struct query* find_query_by_id(ares_channel channel, int id) | ||||||
| { | { | ||||||
|   int qid; |   unsigned short qid; | ||||||
|   struct query* q; |   struct list_node* list_head; | ||||||
|  |   struct list_node* list_node; | ||||||
|   DNS_HEADER_SET_QID(((unsigned char*)&qid), id); |   DNS_HEADER_SET_QID(((unsigned char*)&qid), id); | ||||||
|  |  | ||||||
|   /* Find the query corresponding to this packet. */ |   /* Find the query corresponding to this packet. */ | ||||||
|   for (q = channel->queries; q; q = q->next) |   list_head = &(channel->queries_by_qid[qid % ARES_QID_TABLE_SIZE]); | ||||||
|  |   for (list_node = list_head->next; list_node != list_head; | ||||||
|  |        list_node = list_node->next) | ||||||
|     { |     { | ||||||
|  |        struct query *q = list_node->data; | ||||||
|        if (q->qid == qid) |        if (q->qid == qid) | ||||||
| 	  return q; | 	  return q; | ||||||
|     } |     } | ||||||
| @@ -110,7 +114,8 @@ void ares_query(ares_channel channel, const char *name, int dnsclass, | |||||||
|                         &qlen); |                         &qlen); | ||||||
|   if (status != ARES_SUCCESS) |   if (status != ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       callback(arg, status, NULL, 0); |       if (qbuf != NULL) free(qbuf); | ||||||
|  |       callback(arg, status, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -121,7 +126,7 @@ void ares_query(ares_channel channel, const char *name, int dnsclass, | |||||||
|   if (!qquery) |   if (!qquery) | ||||||
|     { |     { | ||||||
|       ares_free_string(qbuf); |       ares_free_string(qbuf); | ||||||
|       callback(arg, ARES_ENOMEM, NULL, 0); |       callback(arg, ARES_ENOMEM, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   qquery->callback = callback; |   qquery->callback = callback; | ||||||
| @@ -132,14 +137,14 @@ void ares_query(ares_channel channel, const char *name, int dnsclass, | |||||||
|   ares_free_string(qbuf); |   ares_free_string(qbuf); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void qcallback(void *arg, int status, unsigned char *abuf, int alen) | static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   struct qquery *qquery = (struct qquery *) arg; |   struct qquery *qquery = (struct qquery *) arg; | ||||||
|   unsigned int ancount; |   unsigned int ancount; | ||||||
|   int rcode; |   int rcode; | ||||||
|  |  | ||||||
|   if (status != ARES_SUCCESS) |   if (status != ARES_SUCCESS) | ||||||
|     qquery->callback(qquery->arg, status, abuf, alen); |     qquery->callback(qquery->arg, status, timeouts, abuf, alen); | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       /* Pull the response code and answer count from the packet. */ |       /* Pull the response code and answer count from the packet. */ | ||||||
| @@ -168,7 +173,7 @@ static void qcallback(void *arg, int status, unsigned char *abuf, int alen) | |||||||
|           status = ARES_EREFUSED; |           status = ARES_EREFUSED; | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|       qquery->callback(qquery->arg, status, abuf, alen); |       qquery->callback(qquery->arg, status, timeouts, abuf, alen); | ||||||
|     } |     } | ||||||
|   free(qquery); |   free(qquery); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ ares_search \- Initiate a DNS query with domain search | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, | .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, | ||||||
| .B	unsigned char *\fIabuf\fP, int \fIalen\fP) | .B	int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP) | ||||||
| .PP | .PP | ||||||
| .B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP, | .B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP, | ||||||
| .B 	int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, | .B 	int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, | ||||||
| @@ -125,6 +125,11 @@ The name service channel | |||||||
| .I channel | .I channel | ||||||
| is being destroyed; the query will not be completed. | is being destroyed; the query will not be completed. | ||||||
| .PP | .PP | ||||||
|  | The callback argument | ||||||
|  | .I timeouts | ||||||
|  | reports how many times a query timed out during the execution of the | ||||||
|  | given request. | ||||||
|  | .PP | ||||||
| If a query completed successfully, the callback argument | If a query completed successfully, the callback argument | ||||||
| .I abuf | .I abuf | ||||||
| points to a result buffer of length | points to a result buffer of length | ||||||
|   | |||||||
| @@ -41,10 +41,12 @@ struct search_query { | |||||||
|   int status_as_is;             /* error status from trying as-is */ |   int status_as_is;             /* error status from trying as-is */ | ||||||
|   int next_domain;              /* next search domain to try */ |   int next_domain;              /* next search domain to try */ | ||||||
|   int trying_as_is;             /* current query is for name as-is */ |   int trying_as_is;             /* current query is for name as-is */ | ||||||
|  |   int timeouts;                 /* number of timeouts we saw for this request */ | ||||||
|  |   int ever_got_nodata;          /* did we ever get ARES_ENODATA along the way? */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void search_callback(void *arg, int status, unsigned char *abuf, | static void search_callback(void *arg, int status, int timeouts, | ||||||
|                             int alen); |                             unsigned char *abuf, int alen); | ||||||
| static void end_squery(struct search_query *squery, int status, | static void end_squery(struct search_query *squery, int status, | ||||||
|                        unsigned char *abuf, int alen); |                        unsigned char *abuf, int alen); | ||||||
| static int cat_domain(const char *name, const char *domain, char **s); | static int cat_domain(const char *name, const char *domain, char **s); | ||||||
| @@ -64,7 +66,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, | |||||||
|   status = single_domain(channel, name, &s); |   status = single_domain(channel, name, &s); | ||||||
|   if (status != ARES_SUCCESS) |   if (status != ARES_SUCCESS) | ||||||
|     { |     { | ||||||
|       callback(arg, status, NULL, 0); |       callback(arg, status, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   if (s) |   if (s) | ||||||
| @@ -80,7 +82,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, | |||||||
|   squery = malloc(sizeof(struct search_query)); |   squery = malloc(sizeof(struct search_query)); | ||||||
|   if (!squery) |   if (!squery) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOMEM, NULL, 0); |       callback(arg, ARES_ENOMEM, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   squery->channel = channel; |   squery->channel = channel; | ||||||
| @@ -88,7 +90,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, | |||||||
|   if (!squery->name) |   if (!squery->name) | ||||||
|     { |     { | ||||||
|       free(squery); |       free(squery); | ||||||
|       callback(arg, ARES_ENOMEM, NULL, 0); |       callback(arg, ARES_ENOMEM, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   squery->dnsclass = dnsclass; |   squery->dnsclass = dnsclass; | ||||||
| @@ -96,6 +98,8 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, | |||||||
|   squery->status_as_is = -1; |   squery->status_as_is = -1; | ||||||
|   squery->callback = callback; |   squery->callback = callback; | ||||||
|   squery->arg = arg; |   squery->arg = arg; | ||||||
|  |   squery->timeouts = 0; | ||||||
|  |   squery->ever_got_nodata = 0; | ||||||
|  |  | ||||||
|   /* Count the number of dots in name. */ |   /* Count the number of dots in name. */ | ||||||
|   ndots = 0; |   ndots = 0; | ||||||
| @@ -132,18 +136,20 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, | |||||||
|         /* failed, free the malloc()ed memory */ |         /* failed, free the malloc()ed memory */ | ||||||
|         free(squery->name); |         free(squery->name); | ||||||
|         free(squery); |         free(squery); | ||||||
|         callback(arg, status, NULL, 0); |         callback(arg, status, 0, NULL, 0); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void search_callback(void *arg, int status, unsigned char *abuf, | static void search_callback(void *arg, int status, int timeouts, | ||||||
|                             int alen) |                             unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   struct search_query *squery = (struct search_query *) arg; |   struct search_query *squery = (struct search_query *) arg; | ||||||
|   ares_channel channel = squery->channel; |   ares_channel channel = squery->channel; | ||||||
|   char *s; |   char *s; | ||||||
|                  |                  | ||||||
|  |   squery->timeouts += timeouts; | ||||||
|  |  | ||||||
|   /* Stop searching unless we got a non-fatal error. */ |   /* Stop searching unless we got a non-fatal error. */ | ||||||
|   if (status != ARES_ENODATA && status != ARES_ESERVFAIL |   if (status != ARES_ENODATA && status != ARES_ESERVFAIL | ||||||
|       && status != ARES_ENOTFOUND) |       && status != ARES_ENOTFOUND) | ||||||
| @@ -153,6 +159,17 @@ static void search_callback(void *arg, int status, unsigned char *abuf, | |||||||
|       /* Save the status if we were trying as-is. */ |       /* Save the status if we were trying as-is. */ | ||||||
|       if (squery->trying_as_is) |       if (squery->trying_as_is) | ||||||
|         squery->status_as_is = status; |         squery->status_as_is = status; | ||||||
|  |  | ||||||
|  |       /*  | ||||||
|  |        * If we ever get ARES_ENODATA along the way, record that; if the search | ||||||
|  |        * should run to the very end and we got at least one ARES_ENODATA, | ||||||
|  |        * then callers like ares_gethostbyname() may want to try a T_A search | ||||||
|  |        * even if the last domain we queried for T_AAAA resource records | ||||||
|  |        * returned ARES_ENOTFOUND. | ||||||
|  |        */ | ||||||
|  |       if (status == ARES_ENODATA) | ||||||
|  |         squery->ever_got_nodata = 1; | ||||||
|  |  | ||||||
|       if (squery->next_domain < channel->ndomains) |       if (squery->next_domain < channel->ndomains) | ||||||
|         { |         { | ||||||
|           /* Try the next domain. */ |           /* Try the next domain. */ | ||||||
| @@ -176,15 +193,20 @@ static void search_callback(void *arg, int status, unsigned char *abuf, | |||||||
|           ares_query(channel, squery->name, squery->dnsclass, squery->type, |           ares_query(channel, squery->name, squery->dnsclass, squery->type, | ||||||
|                      search_callback, squery); |                      search_callback, squery); | ||||||
|         } |         } | ||||||
|  |       else { | ||||||
|  |         if (squery->status_as_is == ARES_ENOTFOUND && squery->ever_got_nodata) { | ||||||
|  |           end_squery(squery, ARES_ENODATA, NULL, 0); | ||||||
|  |         } | ||||||
|         else |         else | ||||||
|           end_squery(squery, squery->status_as_is, NULL, 0); |           end_squery(squery, squery->status_as_is, NULL, 0); | ||||||
|       } |       } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void end_squery(struct search_query *squery, int status, | static void end_squery(struct search_query *squery, int status, | ||||||
|                        unsigned char *abuf, int alen) |                        unsigned char *abuf, int alen) | ||||||
| { | { | ||||||
|   squery->callback(squery->arg, status, abuf, alen); |   squery->callback(squery->arg, status, squery->timeouts, abuf, alen); | ||||||
|   free(squery->name); |   free(squery->name); | ||||||
|   free(squery); |   free(squery); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ ares_send \- Initiate a DNS query | |||||||
| .B #include <ares.h> | .B #include <ares.h> | ||||||
| .PP | .PP | ||||||
| .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, | .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, | ||||||
| .B	unsigned char *\fIabuf\fP, int \fIalen\fP) | .B	int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP) | ||||||
| .PP | .PP | ||||||
| .B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP, | .B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP, | ||||||
| .B 	int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP) | .B 	int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP) | ||||||
| @@ -79,6 +79,11 @@ The name service channel | |||||||
| .I channel | .I channel | ||||||
| is being destroyed; the query will not be completed. | is being destroyed; the query will not be completed. | ||||||
| .PP | .PP | ||||||
|  | The callback argument | ||||||
|  | .I timeouts | ||||||
|  | reports how many times a query timed out during the execution of the | ||||||
|  | given request. | ||||||
|  | .PP | ||||||
| If the query completed, the callback argument | If the query completed, the callback argument | ||||||
| .I abuf | .I abuf | ||||||
| points to a result buffer of length | points to a result buffer of length | ||||||
|   | |||||||
| @@ -39,12 +39,12 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, | |||||||
| { | { | ||||||
|   struct query *query; |   struct query *query; | ||||||
|   int i; |   int i; | ||||||
|   time_t now; |   struct timeval now; | ||||||
|  |  | ||||||
|   /* Verify that the query is at least long enough to hold the header. */ |   /* Verify that the query is at least long enough to hold the header. */ | ||||||
|   if (qlen < HFIXEDSZ || qlen >= (1 << 16)) |   if (qlen < HFIXEDSZ || qlen >= (1 << 16)) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_EBADQUERY, NULL, 0); |       callback(arg, ARES_EBADQUERY, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -52,28 +52,30 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, | |||||||
|   query = malloc(sizeof(struct query)); |   query = malloc(sizeof(struct query)); | ||||||
|   if (!query) |   if (!query) | ||||||
|     { |     { | ||||||
|       callback(arg, ARES_ENOMEM, NULL, 0); |       callback(arg, ARES_ENOMEM, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   query->tcpbuf = malloc(qlen + 2); |   query->tcpbuf = malloc(qlen + 2); | ||||||
|   if (!query->tcpbuf) |   if (!query->tcpbuf) | ||||||
|     { |     { | ||||||
|       free(query); |       free(query); | ||||||
|       callback(arg, ARES_ENOMEM, NULL, 0); |       callback(arg, ARES_ENOMEM, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   query->skip_server = malloc(channel->nservers * sizeof(int)); |   query->server_info = malloc(channel->nservers * | ||||||
|   if (!query->skip_server) |                               sizeof(query->server_info[0])); | ||||||
|  |   if (!query->server_info) | ||||||
|     { |     { | ||||||
|       free(query->tcpbuf); |       free(query->tcpbuf); | ||||||
|       free(query); |       free(query); | ||||||
|       callback(arg, ARES_ENOMEM, NULL, 0); |       callback(arg, ARES_ENOMEM, 0, NULL, 0); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   /* Compute the query ID.  Start with no timeout. */ |   /* Compute the query ID.  Start with no timeout. */ | ||||||
|   query->qid = (unsigned short)DNS_HEADER_QID(qbuf); |   query->qid = (unsigned short)DNS_HEADER_QID(qbuf); | ||||||
|   query->timeout = 0; |   query->timeout.tv_sec = 0; | ||||||
|  |   query->timeout.tv_usec = 0; | ||||||
|  |  | ||||||
|   /* Form the TCP query buffer by prepending qlen (as two |   /* Form the TCP query buffer by prepending qlen (as two | ||||||
|    * network-order bytes) to qbuf. |    * network-order bytes) to qbuf. | ||||||
| @@ -93,15 +95,30 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, | |||||||
|   query->try = 0; |   query->try = 0; | ||||||
|   query->server = 0; |   query->server = 0; | ||||||
|   for (i = 0; i < channel->nservers; i++) |   for (i = 0; i < channel->nservers; i++) | ||||||
|     query->skip_server[i] = 0; |     { | ||||||
|  |       query->server_info[i].skip_server = 0; | ||||||
|  |       query->server_info[i].tcp_connection_generation = 0; | ||||||
|  |     } | ||||||
|   query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ; |   query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ; | ||||||
|   query->error_status = ARES_ECONNREFUSED; |   query->error_status = ARES_ECONNREFUSED; | ||||||
|  |   query->timeouts = 0; | ||||||
|  |  | ||||||
|   /* Chain the query into this channel's query list. */ |   /* Initialize our list nodes. */ | ||||||
|   query->next = channel->queries; |   ares__init_list_node(&(query->queries_by_qid),     query); | ||||||
|   channel->queries = query; |   ares__init_list_node(&(query->queries_by_timeout), query); | ||||||
|  |   ares__init_list_node(&(query->queries_to_server),  query); | ||||||
|  |   ares__init_list_node(&(query->all_queries),        query); | ||||||
|  |  | ||||||
|  |   /* Chain the query into the list of all queries. */ | ||||||
|  |   ares__insert_in_list(&(query->all_queries), &(channel->all_queries)); | ||||||
|  |   /* Keep track of queries bucketed by qid, so we can process DNS | ||||||
|  |    * responses quickly. | ||||||
|  |    */ | ||||||
|  |   ares__insert_in_list( | ||||||
|  |     &(query->queries_by_qid), | ||||||
|  |     &(channel->queries_by_qid[query->qid % ARES_QID_TABLE_SIZE])); | ||||||
|  |  | ||||||
|   /* Perform the first query action. */ |   /* Perform the first query action. */ | ||||||
|   time(&now); |   now = ares__tvnow(); | ||||||
|   ares__send_query(channel, query, now); |   ares__send_query(channel, query, &now); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -46,6 +46,8 @@ const char *ares_strerror(int code) | |||||||
|     "Illegal hints flags specified" |     "Illegal hints flags specified" | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   DEBUGASSERT(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext))); |   if(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext))) | ||||||
|     return errtext[code]; |     return errtext[code]; | ||||||
|  |   else | ||||||
|  |     return "unknown"; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,40 +26,54 @@ | |||||||
| #include "ares.h" | #include "ares.h" | ||||||
| #include "ares_private.h" | #include "ares_private.h" | ||||||
|  |  | ||||||
|  | /* WARNING: Beware that this is linear in the number of outstanding | ||||||
|  |  * requests! You are probably far better off just calling ares_process() | ||||||
|  |  * once per second, rather than calling ares_timeout() to figure out | ||||||
|  |  * when to next call ares_process(). | ||||||
|  |  */ | ||||||
| struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, | struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, | ||||||
|                              struct timeval *tvbuf) |                              struct timeval *tvbuf) | ||||||
| { | { | ||||||
|   struct query *query; |   struct query *query; | ||||||
|   time_t now; |   struct list_node* list_head; | ||||||
|   time_t offset, min_offset; /* these use time_t since some 32 bit systems |   struct list_node* list_node; | ||||||
|                                 still use 64 bit time_t! (like VS2005) */ |   struct timeval now; | ||||||
|  |   struct timeval nextstop; | ||||||
|  |   long offset, min_offset; | ||||||
|  |  | ||||||
|   /* No queries, no timeout (and no fetch of the current time). */ |   /* No queries, no timeout (and no fetch of the current time). */ | ||||||
|   if (!channel->queries) |   if (ares__is_list_empty(&(channel->all_queries))) | ||||||
|     return maxtv; |     return maxtv; | ||||||
|  |  | ||||||
|   /* Find the minimum timeout for the current set of queries. */ |   /* Find the minimum timeout for the current set of queries. */ | ||||||
|   time(&now); |   now = ares__tvnow(); | ||||||
|   min_offset = -1; |   min_offset = -1; | ||||||
|   for (query = channel->queries; query; query = query->next) |  | ||||||
|  |   list_head = &(channel->all_queries); | ||||||
|  |   for (list_node = list_head->next; list_node != list_head; | ||||||
|  |        list_node = list_node->next) | ||||||
|     { |     { | ||||||
|       if (query->timeout == 0) |       query = list_node->data; | ||||||
|  |       if (query->timeout.tv_sec == 0) | ||||||
|         continue; |         continue; | ||||||
|       offset = query->timeout - now; |       offset = ares__timeoffset(&now, &query->timeout); | ||||||
|       if (offset < 0) |       if (offset < 0) | ||||||
|         offset = 0; |         offset = 0; | ||||||
|       if (min_offset == -1 || offset < min_offset) |       if (min_offset == -1 || offset < min_offset) | ||||||
|         min_offset = offset; |         min_offset = offset; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   /* If we found a minimum timeout and it's sooner than the one |   if(min_offset != -1) { | ||||||
|    * specified in maxtv (if any), return it.  Otherwise go with |     nextstop.tv_sec = min_offset/1000; | ||||||
|    * maxtv. |     nextstop.tv_usec = (min_offset%1000)*1000; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* If we found a minimum timeout and it's sooner than the one specified in | ||||||
|  |    * maxtv (if any), return it.  Otherwise go with maxtv. | ||||||
|    */ |    */ | ||||||
|   if (min_offset != -1 && (!maxtv || min_offset <= maxtv->tv_sec)) |   if (min_offset != -1 && (!maxtv || ares__timedout(maxtv, &nextstop))) | ||||||
|     { |     { | ||||||
|       tvbuf->tv_sec = (long)min_offset; |       *tvbuf = nextstop; | ||||||
|       tvbuf->tv_usec = 0; |  | ||||||
|       return tvbuf; |       return tvbuf; | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ | |||||||
| #define ARES__VERSION_H | #define ARES__VERSION_H | ||||||
|  |  | ||||||
| #define ARES_VERSION_MAJOR 1 | #define ARES_VERSION_MAJOR 1 | ||||||
| #define ARES_VERSION_MINOR 4 | #define ARES_VERSION_MINOR 5 | ||||||
| #define ARES_VERSION_PATCH 1 | #define ARES_VERSION_PATCH 4 | ||||||
| #define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\ | #define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\ | ||||||
|                        (ARES_VERSION_MINOR<<8)|\ |                        (ARES_VERSION_MINOR<<8)|\ | ||||||
|                        (ARES_VERSION_PATCH)) |                        (ARES_VERSION_PATCH)) | ||||||
| #define ARES_VERSION_STR "1.4.1-CVS" | #define ARES_VERSION_STR "1.5.4-CVS" | ||||||
|  |  | ||||||
| #ifdef  __cplusplus | #ifdef  __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
|   | |||||||
| @@ -3,7 +3,8 @@ | |||||||
|  |  | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* | /* Copyright (C) 2005 by Dominick Meglio | ||||||
|  |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
|  * fee is hereby granted, provided that the above copyright |  * fee is hereby granted, provided that the above copyright | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
|  |  | ||||||
| ${LIBTOOLIZE:-libtoolize} --copy --automake --force | ${LIBTOOLIZE:-libtoolize} --copy --automake --force | ||||||
| ${ACLOCAL:-aclocal} $ACLOCAL_FLAGS | ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS | ||||||
| ${AUTOHEADER:-autoheader} | ${AUTOHEADER:-autoheader} | ||||||
| ${AUTOCONF:-autoconf} | ${AUTOCONF:-autoconf} | ||||||
| ${AUTOMAKE:-automake} --add-missing | ${AUTOMAKE:-automake} --add-missing | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
|  |  | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright (C) 2004 - 2006 by Daniel Stenberg et al | /* Copyright (C) 2004 - 2008 by Daniel Stenberg et al | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this software and its |  * Permission to use, copy, modify, and distribute this software and its | ||||||
|  * documentation for any purpose and without fee is hereby granted, provided |  * documentation for any purpose and without fee is hereby granted, provided | ||||||
| @@ -97,6 +97,30 @@ | |||||||
| /* Define to the function return type for recv. */ | /* Define to the function return type for recv. */ | ||||||
| #define RECV_TYPE_RETV int | #define RECV_TYPE_RETV int | ||||||
|  |  | ||||||
|  | /* Define if you have the recvfrom function. */ | ||||||
|  | #define HAVE_RECVFROM 1 | ||||||
|  |  | ||||||
|  | /* Define to the type of arg 1 for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_ARG1 SOCKET | ||||||
|  |  | ||||||
|  | /* Define to the type pointed by arg 2 for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_ARG2 char | ||||||
|  |  | ||||||
|  | /* Define to the type of arg 3 for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_ARG3 int | ||||||
|  |  | ||||||
|  | /* Define to the type of arg 4 for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_ARG4 int | ||||||
|  |  | ||||||
|  | /* Define to the type pointed by arg 5 for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_ARG5 struct sockaddr | ||||||
|  |  | ||||||
|  | /* Define to the type pointed by arg 6 for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_ARG6 int | ||||||
|  |  | ||||||
|  | /* Define to the function return type for recvfrom. */ | ||||||
|  | #define RECVFROM_TYPE_RETV int | ||||||
|  |  | ||||||
| /* Define if you have the send function. */ | /* Define if you have the send function. */ | ||||||
| #define HAVE_SEND 1 | #define HAVE_SEND 1 | ||||||
|  |  | ||||||
| @@ -146,11 +170,6 @@ | |||||||
| #define ssize_t int | #define ssize_t int | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* Define to 'int' if socklen_t is not an available 'typedefed' type */ |  | ||||||
| #ifndef HAVE_WS2TCPIP_H |  | ||||||
| #define socklen_t int |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| /* ---------------------------------------------------------------- */ | /* ---------------------------------------------------------------- */ | ||||||
| /*                          STRUCT RELATED                          */ | /*                          STRUCT RELATED                          */ | ||||||
| /* ---------------------------------------------------------------- */ | /* ---------------------------------------------------------------- */ | ||||||
| @@ -164,24 +183,58 @@ | |||||||
| /* Define this if you have struct timeval */ | /* Define this if you have struct timeval */ | ||||||
| #define HAVE_STRUCT_TIMEVAL 1 | #define HAVE_STRUCT_TIMEVAL 1 | ||||||
|  |  | ||||||
|  | /* ---------------------------------------------------------------- */ | ||||||
|  | /*                        COMPILER SPECIFIC                         */ | ||||||
|  | /* ---------------------------------------------------------------- */ | ||||||
|  |  | ||||||
|  | /* Define to avoid VS2005 complaining about portable C functions */ | ||||||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1400) | ||||||
|  | #define _CRT_SECURE_NO_DEPRECATE 1 | ||||||
|  | #define _CRT_NONSTDC_NO_DEPRECATE 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /* VS2008 does not support Windows build targets prior to WinXP, */ | ||||||
|  | /* so, if no build target has been defined we will target WinXP. */ | ||||||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1500) | ||||||
|  | #  ifndef _WIN32_WINNT | ||||||
|  | #    define _WIN32_WINNT 0x0501 | ||||||
|  | #  endif | ||||||
|  | #  ifndef WINVER | ||||||
|  | #    define WINVER 0x0501 | ||||||
|  | #  endif | ||||||
|  | #  if (_WIN32_WINNT < 0x0501) || (WINVER < 0x0501) | ||||||
|  | #    error VS2008 does not support Windows build targets prior to WinXP | ||||||
|  | #  endif | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* ---------------------------------------------------------------- */ | /* ---------------------------------------------------------------- */ | ||||||
| /*                         IPV6 COMPATIBILITY                       */ | /*                         IPV6 COMPATIBILITY                       */ | ||||||
| /* ---------------------------------------------------------------- */ | /* ---------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| /* Define this if you have address family AF_INET6 */ | /* Define this if you have address family AF_INET6 */ | ||||||
|  | #ifdef HAVE_WINSOCK2_H | ||||||
| #define HAVE_AF_INET6 1 | #define HAVE_AF_INET6 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* Define this if you have protocol family PF_INET6 */ | /* Define this if you have protocol family PF_INET6 */ | ||||||
|  | #ifdef HAVE_WINSOCK2_H | ||||||
| #define HAVE_PF_INET6 1 | #define HAVE_PF_INET6 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* Define this if you have struct in6_addr */ | /* Define this if you have struct in6_addr */ | ||||||
|  | #ifdef HAVE_WS2TCPIP_H | ||||||
| #define HAVE_STRUCT_IN6_ADDR 1 | #define HAVE_STRUCT_IN6_ADDR 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* Define this if you have struct sockaddr_in6 */ | /* Define this if you have struct sockaddr_in6 */ | ||||||
|  | #ifdef HAVE_WS2TCPIP_H | ||||||
| #define HAVE_STRUCT_SOCKADDR_IN6 1 | #define HAVE_STRUCT_SOCKADDR_IN6 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* Define this if you have sockaddr_in6 with scopeid */ | /* Define this if you have sockaddr_in6 with scopeid */ | ||||||
|  | #ifdef HAVE_WS2TCPIP_H | ||||||
| #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 | #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif  /* __ARES_CONFIG_WIN32_H */ | #endif  /* __ARES_CONFIG_WIN32_H */ | ||||||
|   | |||||||
| @@ -1,11 +1,60 @@ | |||||||
|  |  | ||||||
| dnl Process this file with autoconf to produce a configure script. |  | ||||||
| AC_PREREQ(2.57) | AC_PREREQ(2.57) | ||||||
| AC_INIT(ares_init.c) |  | ||||||
|  | dnl Version not hardcoded here. Fetched later from ares_version.h | ||||||
|  | AC_INIT([c-ares], [-], | ||||||
|  |   [c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares]) | ||||||
|  |  | ||||||
| AC_CONFIG_SRCDIR([ares_ipv6.h]) | AC_CONFIG_SRCDIR([ares_ipv6.h]) | ||||||
| AM_CONFIG_HEADER(config.h) | AM_CONFIG_HEADER([config.h]) | ||||||
| AM_MAINTAINER_MODE | AM_MAINTAINER_MODE | ||||||
| AM_INIT_AUTOMAKE(c-ares, CVS) |  | ||||||
|  | dnl SED is mandatory for configure process and libtool. | ||||||
|  | dnl Set it now, allowing it to be changed later. | ||||||
|  | AC_PATH_PROG([SED], [sed], [not_found], | ||||||
|  |   [$PATH:/usr/bin:/usr/local/bin]) | ||||||
|  | if test -z "$SED" || test "$SED" = "not_found"; then | ||||||
|  |   AC_MSG_ERROR([sed not found in PATH. Cannot continue without sed.]) | ||||||
|  | fi | ||||||
|  | AC_SUBST([SED]) | ||||||
|  |  | ||||||
|  | dnl GREP is mandatory for configure process and libtool. | ||||||
|  | dnl Set it now, allowing it to be changed later. | ||||||
|  | AC_PATH_PROG([GREP], [grep], [not_found], | ||||||
|  |   [$PATH:/usr/bin:/usr/local/bin]) | ||||||
|  | if test -z "$GREP" || test "$GREP" = "not_found"; then | ||||||
|  |   AC_MSG_ERROR([grep not found in PATH. Cannot continue without grep.]) | ||||||
|  | fi | ||||||
|  | AC_SUBST([GREP]) | ||||||
|  |  | ||||||
|  | dnl EGREP is mandatory for configure process and libtool. | ||||||
|  | dnl Set it now, allowing it to be changed later. | ||||||
|  | if echo a | ($GREP -E '(a|b)') >/dev/null 2>&1; then | ||||||
|  |   AC_MSG_CHECKING([for egrep]) | ||||||
|  |   EGREP="$GREP -E" | ||||||
|  |   AC_MSG_RESULT([$EGREP]) | ||||||
|  | else | ||||||
|  |   AC_PATH_PROG([EGREP], [egrep], [not_found], | ||||||
|  |     [$PATH:/usr/bin:/usr/local/bin]) | ||||||
|  | fi | ||||||
|  | if test -z "$EGREP" || test "$EGREP" = "not_found"; then | ||||||
|  |   AC_MSG_ERROR([egrep not found in PATH. Cannot continue without egrep.]) | ||||||
|  | fi | ||||||
|  | AC_SUBST([EGREP]) | ||||||
|  |  | ||||||
|  | dnl AR is mandatory for configure process and libtool. | ||||||
|  | dnl This is target dependant, so check it as a tool. | ||||||
|  | AC_PATH_TOOL([AR], [ar], [not_found], | ||||||
|  |   [$PATH:/usr/bin:/usr/local/bin]) | ||||||
|  | if test -z "$AR" || test "$AR" = "not_found"; then | ||||||
|  |   AC_MSG_ERROR([ar not found in PATH. Cannot continue without ar.]) | ||||||
|  | fi | ||||||
|  | AC_SUBST([AR]) | ||||||
|  |  | ||||||
|  | dnl Fetch c-ares version from ares_version.h | ||||||
|  | VERSION=`$SED -ne 's/^#define ARES_VERSION_STR "\(.*\)"/\1/p' ${srcdir}/ares_version.h` | ||||||
|  | AM_INIT_AUTOMAKE([c-ares], [$VERSION]) | ||||||
|  | AC_MSG_CHECKING([c-ares version]) | ||||||
|  | AC_MSG_RESULT([$VERSION]) | ||||||
|  |  | ||||||
| dnl | dnl | ||||||
| dnl Detect the canonical host and target build environment | dnl Detect the canonical host and target build environment | ||||||
| @@ -15,12 +64,21 @@ AC_CANONICAL_HOST | |||||||
| dnl Get system canonical name | dnl Get system canonical name | ||||||
| AC_DEFINE_UNQUOTED(OS, "${host}", [cpu-machine-OS]) | AC_DEFINE_UNQUOTED(OS, "${host}", [cpu-machine-OS]) | ||||||
|  |  | ||||||
| AC_AIX |  | ||||||
| AC_PROG_CC | AC_PROG_CC | ||||||
|  | AM_PROG_CC_C_O | ||||||
| AC_PROG_INSTALL | AC_PROG_INSTALL | ||||||
|  |  | ||||||
|  | dnl This defines _ALL_SOURCE for AIX | ||||||
|  | CARES_CHECK_AIX_ALL_SOURCE | ||||||
|  |  | ||||||
|  | dnl Our configure and build reentrant settings | ||||||
|  | CARES_CONFIGURE_REENTRANT | ||||||
|  |  | ||||||
|  | dnl check for how to do large files | ||||||
|  | AC_SYS_LARGEFILE | ||||||
|  |  | ||||||
| case $host_os in | case $host_os in | ||||||
| solaris*) |   solaris*) | ||||||
|     AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used]) |     AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used]) | ||||||
|     ;; |     ;; | ||||||
| esac | esac | ||||||
| @@ -46,6 +104,8 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]), | |||||||
|     dnl when doing the debug stuff, use static library only |     dnl when doing the debug stuff, use static library only | ||||||
|     AC_DISABLE_SHARED |     AC_DISABLE_SHARED | ||||||
|  |  | ||||||
|  |     debugbuild="yes" | ||||||
|  |  | ||||||
|     dnl the entire --enable-debug is a hack that lives and runs on top of |     dnl the entire --enable-debug is a hack that lives and runs on top of | ||||||
|     dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier |     dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier | ||||||
|     AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) |     AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) | ||||||
| @@ -53,15 +113,6 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]), | |||||||
|     CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include" |     CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include" | ||||||
|     CFLAGS="$CFLAGS -g"  |     CFLAGS="$CFLAGS -g"  | ||||||
|  |  | ||||||
|     dnl check for how to do large files, needed to get the curl_off_t check |  | ||||||
|     dnl done right |  | ||||||
|     AC_SYS_LARGEFILE |  | ||||||
|  |  | ||||||
|     AC_CHECK_SIZEOF(curl_off_t, ,[ |  | ||||||
| #include <stdio.h> |  | ||||||
| #include "$srcdir/../include/curl/curl.h" |  | ||||||
|     ]) |  | ||||||
|  |  | ||||||
|     dnl set compiler "debug" options to become more picky, and remove |     dnl set compiler "debug" options to become more picky, and remove | ||||||
|     dnl optimize options from CFLAGS |     dnl optimize options from CFLAGS | ||||||
|     CURL_CC_DEBUG_OPTS |     CURL_CC_DEBUG_OPTS | ||||||
| @@ -70,16 +121,22 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]), | |||||||
|   esac ], |   esac ], | ||||||
|        AC_MSG_RESULT(no) |        AC_MSG_RESULT(no) | ||||||
| ) | ) | ||||||
|  | AM_CONDITIONAL(DEBUGBUILD, test x$debugbuild = xyes) | ||||||
|  | AM_CONDITIONAL(CURLDEBUG, test x$debugbuild = xyes) | ||||||
|  |  | ||||||
| dnl skip libtool C++ and Fortran compiler checks | dnl skip libtool C++ and Fortran compiler checks | ||||||
| m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])]) | m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])]) | ||||||
| m4_defun([AC_PROG_CXX],[]) | m4_defun([AC_PROG_CXX],[]) | ||||||
|  | m4_ifdef([AC_PROG_CXXCPP], [m4_undefine([AC_PROG_CXXCPP])]) | ||||||
|  | m4_defun([AC_PROG_CXXCPP],[true]) | ||||||
| m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])]) | m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])]) | ||||||
| m4_defun([AC_PROG_F77],[]) | m4_defun([AC_PROG_F77],[]) | ||||||
|  |  | ||||||
| dnl skip libtool C++ and Fortran linker checks | dnl skip libtool C++ and Fortran linker checks | ||||||
| m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])]) | m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])]) | ||||||
| m4_defun([AC_LIBTOOL_CXX],[]) | m4_defun([AC_LIBTOOL_CXX],[]) | ||||||
|  | m4_ifdef([AC_LIBTOOL_CXXCPP], [m4_undefine([AC_LIBTOOL_CXXCPP])]) | ||||||
|  | m4_defun([AC_LIBTOOL_CXXCPP],[true]) | ||||||
| m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])]) | m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])]) | ||||||
| m4_defun([AC_LIBTOOL_F77],[]) | m4_defun([AC_LIBTOOL_F77],[]) | ||||||
|  |  | ||||||
| @@ -100,7 +157,7 @@ AC_PROG_LIBTOOL | |||||||
|  |  | ||||||
| AC_MSG_CHECKING([if we need -no-undefined]) | AC_MSG_CHECKING([if we need -no-undefined]) | ||||||
| case $host in | case $host in | ||||||
|   *-*-cygwin | *-*-mingw* | *-*-pw32*) |   *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) | ||||||
|     need_no_undefined=yes |     need_no_undefined=yes | ||||||
|     ;; |     ;; | ||||||
|   *) |   *) | ||||||
| @@ -117,6 +174,110 @@ dnl gethostbyname_r() version | |||||||
| dnl ********************************************************************** | dnl ********************************************************************** | ||||||
| CURL_DETECT_ICC([CFLAGS="$CFLAGS -we 147"]) | CURL_DETECT_ICC([CFLAGS="$CFLAGS -we 147"]) | ||||||
|  |  | ||||||
|  | dnl ********************************************************************** | ||||||
|  | dnl platform/compiler/architecture specific checks/flags | ||||||
|  | dnl ********************************************************************** | ||||||
|  |  | ||||||
|  | case $host in | ||||||
|  |   # | ||||||
|  |   x86_64*linux*) | ||||||
|  |     # | ||||||
|  |     dnl find out if icc is being used | ||||||
|  |     if test "z$ICC" = "z"; then | ||||||
|  |       CURL_DETECT_ICC | ||||||
|  |     fi | ||||||
|  |     # | ||||||
|  |     if test "$ICC" = "yes"; then | ||||||
|  |       dnl figure out icc version | ||||||
|  |       AC_MSG_CHECKING([icc version]) | ||||||
|  |       iccver=`$CC -dumpversion` | ||||||
|  |       iccnhi=`echo $iccver | cut -d . -f1` | ||||||
|  |       iccnlo=`echo $iccver | cut -d . -f2` | ||||||
|  |       iccnum=`(expr $iccnhi "*" 100 + $iccnlo) 2>/dev/null` | ||||||
|  |       AC_MSG_RESULT($iccver) | ||||||
|  |       # | ||||||
|  |       if test "$iccnum" -ge "900" && test "$iccnum" -lt "1000"; then | ||||||
|  |         dnl icc 9.X specific | ||||||
|  |         CFLAGS="$CFLAGS -i-dynamic" | ||||||
|  |       fi | ||||||
|  |       # | ||||||
|  |       if test "$iccnum" -ge "1000"; then | ||||||
|  |         dnl icc 10.X or later | ||||||
|  |         CFLAGS="$CFLAGS -shared-intel" | ||||||
|  |       fi | ||||||
|  |       # | ||||||
|  |     fi | ||||||
|  |     ;; | ||||||
|  |   # | ||||||
|  | esac | ||||||
|  |  | ||||||
|  | AC_MSG_CHECKING([whether we are using the IBM C compiler]) | ||||||
|  | CURL_CHECK_DEF([__IBMC__], [], [silent]) | ||||||
|  | if test "$curl_cv_have_def___IBMC__" = "yes"; then | ||||||
|  |   AC_MSG_RESULT([yes]) | ||||||
|  |   dnl Ensure that compiler optimizations are always thread-safe. | ||||||
|  |   CFLAGS="$CFLAGS -qthreaded" | ||||||
|  |   dnl Disable type based strict aliasing optimizations, using worst | ||||||
|  |   dnl case aliasing assumptions when compiling. Type based aliasing | ||||||
|  |   dnl would restrict the lvalues that could be safely used to access | ||||||
|  |   dnl a data object. | ||||||
|  |   CFLAGS="$CFLAGS -qnoansialias" | ||||||
|  |   dnl Force compiler to stop after the compilation phase, without | ||||||
|  |   dnl generating an object code file when compilation has errors. | ||||||
|  |   CFLAGS="$CFLAGS -qhalt=e" | ||||||
|  | else | ||||||
|  |   AC_MSG_RESULT([no]) | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | AC_MSG_CHECKING([whether we are using the DEC/Compaq C compiler]) | ||||||
|  | CURL_CHECK_DEF([__DECC], [], [silent]) | ||||||
|  | CURL_CHECK_DEF([__DECC_VER], [], [silent]) | ||||||
|  | if test "$curl_cv_have_def___DECC" = "yes" && | ||||||
|  |   test "$curl_cv_have_def___DECC_VER" = "yes"; then | ||||||
|  |   AC_MSG_RESULT([yes]) | ||||||
|  |   dnl Select strict ANSI C compiler mode | ||||||
|  |   CFLAGS="$CFLAGS -std1" | ||||||
|  |   dnl Turn off optimizer ANSI C aliasing rules | ||||||
|  |   CFLAGS="$CFLAGS -noansi_alias" | ||||||
|  |   dnl Select a higher warning level than default level2 | ||||||
|  |   CFLAGS="$CFLAGS -msg_enable level3" | ||||||
|  |   dnl Generate warnings for missing function prototypes | ||||||
|  |   CFLAGS="$CFLAGS -warnprotos" | ||||||
|  |   dnl Change some warnings into fatal errors | ||||||
|  |   CFLAGS="$CFLAGS -msg_fatal toofewargs,toomanyargs" | ||||||
|  | else | ||||||
|  |   AC_MSG_RESULT([no]) | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | CURL_CHECK_COMPILER_HALT_ON_ERROR | ||||||
|  | CURL_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE | ||||||
|  |  | ||||||
|  | dnl ********************************************************************** | ||||||
|  | dnl Compilation based checks should not be done before this point. | ||||||
|  | dnl ********************************************************************** | ||||||
|  |  | ||||||
|  | dnl ********************************************************************** | ||||||
|  | dnl Make sure that our checks for headers windows.h winsock.h winsock2.h  | ||||||
|  | dnl and ws2tcpip.h take precedence over any other further checks which  | ||||||
|  | dnl could be done later using AC_CHECK_HEADER or AC_CHECK_HEADERS for | ||||||
|  | dnl this specific header files. And do them before its results are used. | ||||||
|  | dnl ********************************************************************** | ||||||
|  |  | ||||||
|  | CURL_CHECK_HEADER_WINDOWS | ||||||
|  | CURL_CHECK_NATIVE_WINDOWS | ||||||
|  | case X-"$ac_cv_native_windows" in | ||||||
|  |   X-yes) | ||||||
|  |     CURL_CHECK_HEADER_WINSOCK | ||||||
|  |     CURL_CHECK_HEADER_WINSOCK2 | ||||||
|  |     CURL_CHECK_HEADER_WS2TCPIP | ||||||
|  |     ;; | ||||||
|  |   *) | ||||||
|  |     ac_cv_header_winsock_h="no" | ||||||
|  |     ac_cv_header_winsock2_h="no" | ||||||
|  |     ac_cv_header_ws2tcpip_h="no" | ||||||
|  |     ;; | ||||||
|  | esac | ||||||
|  |  | ||||||
| dnl ********************************************************************** | dnl ********************************************************************** | ||||||
| dnl Checks for libraries. | dnl Checks for libraries. | ||||||
| dnl ********************************************************************** | dnl ********************************************************************** | ||||||
| @@ -147,49 +308,107 @@ then | |||||||
|   AC_MSG_CHECKING([for gethostbyname with both nsl and socket libs]) |   AC_MSG_CHECKING([for gethostbyname with both nsl and socket libs]) | ||||||
|   my_ac_save_LIBS=$LIBS |   my_ac_save_LIBS=$LIBS | ||||||
|   LIBS="-lnsl -lsocket $LIBS" |   LIBS="-lnsl -lsocket $LIBS" | ||||||
|   AC_TRY_LINK( , |   AC_LINK_IFELSE([ | ||||||
|              [gethostbyname();], |     AC_LANG_PROGRAM([[ | ||||||
|              [ dnl found it! |     ]],[[ | ||||||
|  |       gethostbyname(); | ||||||
|  |     ]]) | ||||||
|  |   ],[ | ||||||
|  |     AC_MSG_RESULT([yes]) | ||||||
|     HAVE_GETHOSTBYNAME="1" |     HAVE_GETHOSTBYNAME="1" | ||||||
|              AC_MSG_RESULT([yes])], |   ],[ | ||||||
|              [ dnl failed! |  | ||||||
|     AC_MSG_RESULT([no]) |     AC_MSG_RESULT([no]) | ||||||
|              dnl restore LIBS |     LIBS=$my_ac_save_LIBS | ||||||
|              LIBS=$my_ac_save_LIBS] |   ]) | ||||||
|              ) |  | ||||||
| fi | fi | ||||||
|  |  | ||||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | if test "$HAVE_GETHOSTBYNAME" != "1" | ||||||
| then | then | ||||||
|   dnl This is for Msys/Mingw |   dnl This is for winsock systems | ||||||
|   AC_MSG_CHECKING([for gethostbyname in ws2_32]) |   if test "$ac_cv_header_windows_h" = "yes"; then | ||||||
|  |     if test "$ac_cv_header_winsock_h" = "yes"; then | ||||||
|  |       case $host in | ||||||
|  |         *-*-mingw32ce*) | ||||||
|  |           winsock_LIB="-lwinsock" | ||||||
|  |           ;; | ||||||
|  |         *) | ||||||
|  |           winsock_LIB="-lwsock32" | ||||||
|  |           ;; | ||||||
|  |       esac | ||||||
|  |     fi | ||||||
|  |     if test "$ac_cv_header_winsock2_h" = "yes"; then | ||||||
|  |       winsock_LIB="-lws2_32" | ||||||
|  |     fi | ||||||
|  |     if test ! -z "$winsock_LIB"; then | ||||||
|       my_ac_save_LIBS=$LIBS |       my_ac_save_LIBS=$LIBS | ||||||
|   LIBS="-lws2_32 $LIBS" |       LIBS="$winsock_LIB $LIBS" | ||||||
|   AC_TRY_LINK([#include <winsock2.h>], |       AC_MSG_CHECKING([for gethostbyname in $winsock_LIB]) | ||||||
|                [gethostbyname("www.dummysite.com");], |       AC_LINK_IFELSE([ | ||||||
|                [ dnl worked! |         AC_LANG_PROGRAM([[ | ||||||
|                ws2="yes" | #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 | ||||||
|  |         ]],[[ | ||||||
|  |           gethostbyname("www.dummysite.com"); | ||||||
|  |         ]]) | ||||||
|  |       ],[ | ||||||
|         AC_MSG_RESULT([yes]) |         AC_MSG_RESULT([yes]) | ||||||
|                HAVE_GETHOSTBYNAME="1"], |         HAVE_GETHOSTBYNAME="1" | ||||||
|                [ dnl failed, restore LIBS |       ],[ | ||||||
|  |         AC_MSG_RESULT([no]) | ||||||
|  |         winsock_LIB="" | ||||||
|         LIBS=$my_ac_save_LIBS |         LIBS=$my_ac_save_LIBS | ||||||
|                AC_MSG_RESULT(no)] |       ]) | ||||||
|              ) |     fi | ||||||
|  |   fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if test "$HAVE_GETHOSTBYNAME" != "1" | ||||||
|  | then | ||||||
|  |   dnl This is for Minix 3.1 | ||||||
|  |   AC_MSG_CHECKING([for gethostbyname for Minix 3]) | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_PROGRAM([[ | ||||||
|  | /* Older Minix versions may need <net/gen/netdb.h> here instead */ | ||||||
|  | #include <netdb.h> | ||||||
|  |     ]],[[ | ||||||
|  |       gethostbyname("www.dummysite.com"); | ||||||
|  |     ]]) | ||||||
|  |   ],[ | ||||||
|  |     AC_MSG_RESULT([yes]) | ||||||
|  |     HAVE_GETHOSTBYNAME="1" | ||||||
|  |   ],[ | ||||||
|  |     AC_MSG_RESULT([no]) | ||||||
|  |   ]) | ||||||
| fi | fi | ||||||
|  |  | ||||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | if test "$HAVE_GETHOSTBYNAME" != "1" | ||||||
| then | then | ||||||
|   dnl This is for eCos with a stubbed DNS implementation |   dnl This is for eCos with a stubbed DNS implementation | ||||||
|   AC_MSG_CHECKING([for gethostbyname for eCos]) |   AC_MSG_CHECKING([for gethostbyname for eCos]) | ||||||
|   AC_TRY_LINK([ |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_PROGRAM([[ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <netdb.h>], | #include <netdb.h> | ||||||
|                [gethostbyname("www.dummysite.com");], |     ]],[[ | ||||||
|                [ dnl worked! |       gethostbyname("www.dummysite.com"); | ||||||
|  |     ]]) | ||||||
|  |   ],[ | ||||||
|     AC_MSG_RESULT([yes]) |     AC_MSG_RESULT([yes]) | ||||||
|                HAVE_GETHOSTBYNAME="1"], |     HAVE_GETHOSTBYNAME="1" | ||||||
|                AC_MSG_RESULT(no) |   ],[ | ||||||
|              ) |     AC_MSG_RESULT([no]) | ||||||
|  |   ]) | ||||||
| fi | fi | ||||||
|  |  | ||||||
| if test "$HAVE_GETHOSTBYNAME" != "1" | if test "$HAVE_GETHOSTBYNAME" != "1" | ||||||
| @@ -221,8 +440,11 @@ fi | |||||||
| dnl socket lib? | dnl socket lib? | ||||||
| AC_CHECK_FUNC(connect, , [ AC_CHECK_LIB(socket, connect) ]) | AC_CHECK_FUNC(connect, , [ AC_CHECK_LIB(socket, connect) ]) | ||||||
|  |  | ||||||
| dnl dl lib? | dnl ********************************************************************** | ||||||
| AC_CHECK_FUNC(dlclose, , [ AC_CHECK_LIB(dl, dlopen) ]) | dnl In case that function clock_gettime with monotonic timer is available, | ||||||
|  | dnl check for additional required libraries. | ||||||
|  | dnl ********************************************************************** | ||||||
|  | CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC | ||||||
|  |  | ||||||
| AC_MSG_CHECKING([whether to use libgcc]) | AC_MSG_CHECKING([whether to use libgcc]) | ||||||
| AC_ARG_ENABLE(libgcc, | AC_ARG_ENABLE(libgcc, | ||||||
| @@ -289,23 +511,6 @@ if test "x$RECENTAIX" = "xyes"; then | |||||||
|  |  | ||||||
|   AC_DEFINE(_THREAD_SAFE, 1, [define this if you need it to compile thread-safe code]) |   AC_DEFINE(_THREAD_SAFE, 1, [define this if you need it to compile thread-safe code]) | ||||||
|  |  | ||||||
|   dnl check if this is the IBM xlc compiler |  | ||||||
|   dnl Details thanks to => http://predef.sourceforge.net/ |  | ||||||
|   AC_MSG_CHECKING([if this is the xlc compiler]) |  | ||||||
|   AC_EGREP_CPP([^__xlC__], [__xlC__], |  | ||||||
|          dnl action if the text is found, this it has not been replaced by the |  | ||||||
|          dnl cpp |  | ||||||
|          XLC="no" |  | ||||||
|          AC_MSG_RESULT([no]), |  | ||||||
|          dnl the text was not found, it was replaced by the cpp |  | ||||||
|          XLC="yes" |  | ||||||
|          AC_MSG_RESULT([yes]) |  | ||||||
|          CFLAGS="$CFLAGS -qthreaded" |  | ||||||
|          dnl AIX xlc has to have strict aliasing turned off. If not, |  | ||||||
|          dnl the optimizer assumes that pointers can only point to |  | ||||||
|          dnl an object of the same type. |  | ||||||
|          CFLAGS="$CFLAGS -qnoansialias" |  | ||||||
|        ) |  | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -316,18 +521,6 @@ dnl ********************************************************************** | |||||||
| dnl Checks for header files. | dnl Checks for header files. | ||||||
| AC_HEADER_STDC | AC_HEADER_STDC | ||||||
|  |  | ||||||
| dnl ********************************************************************** |  | ||||||
| dnl Make sure that our checks for headers windows.h winsock.h winsock2.h  |  | ||||||
| dnl and ws2tcpip.h take precedence over any other further checks which  |  | ||||||
| dnl could be done later using AC_CHECK_HEADER or AC_CHECK_HEADERS for |  | ||||||
| dnl this specific header files. And do them before its results are used. |  | ||||||
| dnl ********************************************************************** |  | ||||||
|  |  | ||||||
| CURL_CHECK_HEADER_WINDOWS |  | ||||||
| CURL_CHECK_HEADER_WINSOCK |  | ||||||
| CURL_CHECK_HEADER_WINSOCK2 |  | ||||||
| CURL_CHECK_HEADER_WS2TCPIP |  | ||||||
|  |  | ||||||
| CURL_CHECK_HEADER_MALLOC | CURL_CHECK_HEADER_MALLOC | ||||||
|  |  | ||||||
| dnl check for a few basic system headers we need | dnl check for a few basic system headers we need | ||||||
| @@ -340,9 +533,12 @@ AC_CHECK_HEADERS( | |||||||
|        sys/param.h \ |        sys/param.h \ | ||||||
|        netdb.h \ |        netdb.h \ | ||||||
|        netinet/in.h \ |        netinet/in.h \ | ||||||
|  |        netinet/tcp.h \ | ||||||
|        net/if.h \ |        net/if.h \ | ||||||
|        errno.h \ |        errno.h \ | ||||||
|  |        strings.h \ | ||||||
|        stdbool.h \ |        stdbool.h \ | ||||||
|  |        time.h \ | ||||||
|        arpa/nameser.h \ |        arpa/nameser.h \ | ||||||
|        arpa/nameser_compat.h \ |        arpa/nameser_compat.h \ | ||||||
|        arpa/inet.h, |        arpa/inet.h, | ||||||
| @@ -386,7 +582,8 @@ AC_CHECK_SIZEOF(long) | |||||||
| AC_CHECK_SIZEOF(time_t) | AC_CHECK_SIZEOF(time_t) | ||||||
|  |  | ||||||
| AC_CHECK_TYPE(long long, | AC_CHECK_TYPE(long long, | ||||||
|    [AC_DEFINE(HAVE_LONGLONG, 1, [if your compiler supports long long])] |    [AC_DEFINE(HAVE_LONGLONG, 1, | ||||||
|  |      [Define to 1 if the compiler supports the 'long long' data type.])] | ||||||
|    longlong="yes"   |    longlong="yes"   | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -429,9 +626,8 @@ TYPE_SIG_ATOMIC_T | |||||||
| AC_TYPE_SIGNAL | AC_TYPE_SIGNAL | ||||||
|  |  | ||||||
| CURL_CHECK_FUNC_RECV | CURL_CHECK_FUNC_RECV | ||||||
|  | CURL_CHECK_FUNC_RECVFROM | ||||||
| CURL_CHECK_FUNC_SEND | CURL_CHECK_FUNC_SEND | ||||||
|  |  | ||||||
| CURL_CHECK_MSG_NOSIGNAL | CURL_CHECK_MSG_NOSIGNAL | ||||||
|  |  | ||||||
| dnl check for AF_INET6 | dnl check for AF_INET6 | ||||||
| @@ -600,23 +796,27 @@ AC_CHECK_MEMBER(struct addrinfo.ai_flags, | |||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
| AC_CHECK_FUNCS( bitncmp \ | AC_CHECK_FUNCS([bitncmp \ | ||||||
|   gettimeofday \ |   gettimeofday \ | ||||||
|                 if_indextoname, |   if_indextoname | ||||||
| dnl if found | ],[ | ||||||
| [], | ],[ | ||||||
| dnl if not found, $ac_func is the name we check for |   func="$ac_func" | ||||||
| func="$ac_func" |   AC_MSG_CHECKING([deeper for $func]) | ||||||
| AC_MSG_CHECKING([deeper for $func]) |   AC_LINK_IFELSE([ | ||||||
| AC_TRY_LINK( [], |     AC_LANG_PROGRAM([[ | ||||||
|              [ $func ();], |     ]],[[ | ||||||
|              AC_MSG_RESULT(yes!) |       $func (); | ||||||
|  |     ]]) | ||||||
|  |   ],[ | ||||||
|  |     AC_MSG_RESULT([yes]) | ||||||
|     eval "ac_cv_func_$func=yes" |     eval "ac_cv_func_$func=yes" | ||||||
|              def=`echo "HAVE_$func" | tr 'a-z' 'A-Z'` |     AC_DEFINE_UNQUOTED([AS_TR_CPP([HAVE_$func])], [1], | ||||||
|              AC_DEFINE_UNQUOTED($def, 1, [If you have $func]), |       [Define to 1 if you have the $func function.]) | ||||||
|              AC_MSG_RESULT(but still no) |   ],[ | ||||||
|              ) |     AC_MSG_RESULT([but still no]) | ||||||
| ) |   ]) | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
| dnl check for inet_pton | dnl check for inet_pton | ||||||
| @@ -793,8 +993,15 @@ AC_HELP_STRING([--with-random=FILE], | |||||||
|                [read randomness from FILE (default=/dev/urandom)]), |                [read randomness from FILE (default=/dev/urandom)]), | ||||||
|     [ RANDOM_FILE="$withval" ], |     [ RANDOM_FILE="$withval" ], | ||||||
|     [ |     [ | ||||||
|         dnl Check for random device |         dnl Check for random device.  If we're cross compiling, we can't | ||||||
|  |         dnl check, and it's better to assume it doesn't exist than it is | ||||||
|  |         dnl to fail on AC_CHECK_FILE or later. | ||||||
|  |         if test "$cross_compiling" = "no"; then | ||||||
|           AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] ) |           AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] ) | ||||||
|  |         else | ||||||
|  |           AC_MSG_WARN([cannot check for /dev/urandom while cross compiling; assuming none]) | ||||||
|  |         fi | ||||||
|  |          | ||||||
|     ] |     ] | ||||||
| ) | ) | ||||||
| if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then | if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then | ||||||
| @@ -803,4 +1010,8 @@ if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then | |||||||
|         [a suitable file/device to read random data from]) |         [a suitable file/device to read random data from]) | ||||||
| fi | fi | ||||||
|  |  | ||||||
| AC_OUTPUT(Makefile) | CARES_PRIVATE_LIBS="$LIBS" | ||||||
|  | AC_SUBST(CARES_PRIVATE_LIBS) | ||||||
|  |  | ||||||
|  | AC_CONFIG_FILES([Makefile libcares.pc]) | ||||||
|  | AC_OUTPUT | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								ares/get_ver.awk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ares/get_ver.awk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | # *************************************************************************** | ||||||
|  | # *  Project: c-ares | ||||||
|  | # * | ||||||
|  | # * $Id$ | ||||||
|  | # *************************************************************************** | ||||||
|  | # awk script which fetches c-ares version number and string from input | ||||||
|  | # file and writes them to STDOUT. Here you can get an awk version for Win32: | ||||||
|  | # http://www.gknw.net/development/prgtools/awk-20070501.zip | ||||||
|  | # | ||||||
|  | BEGIN { | ||||||
|  |   if (match (ARGV[1], /ares_version.h/)) { | ||||||
|  |     while ((getline < ARGV[1]) > 0) { | ||||||
|  |       if (match ($0, /^#define ARES_COPYRIGHT "[^"]+"$/)) { | ||||||
|  |         libcares_copyright_str = substr($0, 25, length($0)-25); | ||||||
|  |       } | ||||||
|  |       else if (match ($0, /^#define ARES_VERSION_STR "[^"]+"$/)) { | ||||||
|  |         libcares_ver_str = substr($3, 2, length($3)-2); | ||||||
|  |       } | ||||||
|  |       else if (match ($0, /^#define ARES_VERSION_MAJOR [0-9]+$/)) { | ||||||
|  |         libcares_ver_major = substr($3, 1, length($3)); | ||||||
|  |       } | ||||||
|  |       else if (match ($0, /^#define ARES_VERSION_MINOR [0-9]+$/)) { | ||||||
|  |         libcares_ver_minor = substr($3, 1, length($3)); | ||||||
|  |       } | ||||||
|  |       else if (match ($0, /^#define ARES_VERSION_PATCH [0-9]+$/)) { | ||||||
|  |         libcares_ver_patch = substr($3, 1, length($3)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     libcares_ver = libcares_ver_major "," libcares_ver_minor "," libcares_ver_patch; | ||||||
|  |     print "LIBCARES_VERSION = " libcares_ver ""; | ||||||
|  |     print "LIBCARES_VERSION_STR = " libcares_ver_str ""; | ||||||
|  |     print "LIBCARES_COPYRIGHT_STR = " libcares_copyright_str ""; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -3,7 +3,8 @@ | |||||||
|  |  | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* | /* Copyright (C) 2005 by Daniel Stenberg | ||||||
|  |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
|  * fee is hereby granted, provided that the above copyright |  * fee is hereby granted, provided that the above copyright | ||||||
|   | |||||||
| @@ -3,7 +3,8 @@ | |||||||
|  |  | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* | /* Copyright (C) 2005 by Dominick Meglio | ||||||
|  |  * | ||||||
|  * Permission to use, copy, modify, and distribute this |  * Permission to use, copy, modify, and distribute this | ||||||
|  * software and its documentation for any purpose and without |  * software and its documentation for any purpose and without | ||||||
|  * fee is hereby granted, provided that the above copyright |  * fee is hereby granted, provided that the above copyright | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								ares/libcares.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								ares/libcares.pc.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | #*************************************************************************** | ||||||
|  | # Project        ___       __ _ _ __ ___  ___  | ||||||
|  | #               / __|____ / _` | '__/ _ \/ __| | ||||||
|  | #              | (_|_____| (_| | | |  __/\__ \ | ||||||
|  | #               \___|     \__,_|_|  \___||___/ | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | prefix=@prefix@ | ||||||
|  | exec_prefix=@exec_prefix@ | ||||||
|  | libdir=@libdir@ | ||||||
|  | includedir=@includedir@ | ||||||
|  |  | ||||||
|  | Name: c-ares | ||||||
|  | URL: http://daniel.haxx.se/projects/c-ares/ | ||||||
|  | Description: asynchronous DNS lookup library | ||||||
|  | Version: @VERSION@ | ||||||
|  | Requires:  | ||||||
|  | Requires.private:  | ||||||
|  | Cflags: -I${includedir} | ||||||
|  | Libs: -L${libdir} -lcares | ||||||
|  | Libs.private: @CARES_PRIVATE_LIBS@ | ||||||
							
								
								
									
										442
									
								
								ares/m4/cares-reentrant.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										442
									
								
								ares/m4/cares-reentrant.m4
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,442 @@ | |||||||
|  | #*************************************************************************** | ||||||
|  | # $Id$ | ||||||
|  | # | ||||||
|  | # Copyright (C) 2008 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. | ||||||
|  | # | ||||||
|  | #*************************************************************************** | ||||||
|  |  | ||||||
|  | # File version for 'aclocal' use. Keep it a single number. | ||||||
|  | # serial 2 | ||||||
|  |  | ||||||
|  | dnl Note 1 | ||||||
|  | dnl ------ | ||||||
|  | dnl None of the CARES_CHECK_NEED_REENTRANT_* macros shall use HAVE_FOO_H to | ||||||
|  | dnl conditionally include header files. These macros are used early in the | ||||||
|  | dnl configure process much before header file availability is known. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_GMTIME_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function gmtime_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_GMTIME_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([gmtime_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_gmtime_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_gmtime_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_gmtime_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([gmtime_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <time.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_gmtime_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([gmtime_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <time.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_gmtime_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_LOCALTIME_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function localtime_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_LOCALTIME_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([localtime_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_localtime_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_localtime_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_localtime_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([localtime_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <time.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_localtime_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([localtime_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <time.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_localtime_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_STRERROR_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function strerror_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_STRERROR_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([strerror_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_strerror_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_strerror_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_strerror_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([strerror_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <string.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_strerror_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([strerror_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <string.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_strerror_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_STRTOK_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function strtok_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_STRTOK_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([strtok_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_strtok_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_strtok_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_strtok_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([strtok_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <string.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_strtok_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([strtok_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <string.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_strtok_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_INET_NTOA_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function inet_ntoa_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_INET_NTOA_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([inet_ntoa_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_inet_ntoa_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_inet_ntoa_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_inet_ntoa_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([inet_ntoa_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <sys/socket.h> | ||||||
|  | #include <netinet/in.h> | ||||||
|  | #include <arpa/inet.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_inet_ntoa_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([inet_ntoa_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <sys/socket.h> | ||||||
|  | #include <netinet/in.h> | ||||||
|  | #include <arpa/inet.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_inet_ntoa_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_GETHOSTBYADDR_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function gethostbyaddr_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_GETHOSTBYADDR_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([gethostbyaddr_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_gethostbyaddr_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_gethostbyaddr_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_gethostbyaddr_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([gethostbyaddr_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_gethostbyaddr_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([gethostbyaddr_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_gethostbyaddr_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function gethostbyname_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([gethostbyname_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_gethostbyname_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_gethostbyname_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_gethostbyname_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([gethostbyname_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_gethostbyname_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([gethostbyname_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_gethostbyname_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_GETPROTOBYNAME_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function getprotobyname_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_GETPROTOBYNAME_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([getprotobyname_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_getprotobyname_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_getprotobyname_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_getprotobyname_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([getprotobyname_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_getprotobyname_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([getprotobyname_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_getprotobyname_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_GETSERVBYPORT_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes function getservbyport_r compiler visible. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_GETSERVBYPORT_R], [ | ||||||
|  |   AC_LINK_IFELSE([ | ||||||
|  |     AC_LANG_FUNC_LINK_TRY([getservbyport_r]) | ||||||
|  |   ],[ | ||||||
|  |     tmp_getservbyport_r="yes" | ||||||
|  |   ],[ | ||||||
|  |     tmp_getservbyport_r="no" | ||||||
|  |   ]) | ||||||
|  |   if test "$tmp_getservbyport_r" = "yes"; then | ||||||
|  |     AC_EGREP_CPP([getservbyport_r],[ | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |     ],[ | ||||||
|  |       tmp_getservbyport_r="proto_declared" | ||||||
|  |     ],[ | ||||||
|  |       AC_EGREP_CPP([getservbyport_r],[ | ||||||
|  | #define _REENTRANT | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <netdb.h> | ||||||
|  |       ],[ | ||||||
|  |         tmp_getservbyport_r="proto_needs_reentrant" | ||||||
|  |         tmp_need_reentrant="yes" | ||||||
|  |       ]) | ||||||
|  |     ]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CHECK_NEED_REENTRANT_FUNCTIONS_R | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl Checks if the preprocessor _REENTRANT definition | ||||||
|  | dnl makes several _r functions compiler visible. | ||||||
|  | dnl Internal macro for CARES_CONFIGURE_REENTRANT. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CHECK_NEED_REENTRANT_FUNCTIONS_R], [ | ||||||
|  |   # | ||||||
|  |   tmp_need_reentrant="no" | ||||||
|  |   # | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_GMTIME_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_LOCALTIME_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_STRERROR_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_STRTOK_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_INET_NTOA_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_GETHOSTBYADDR_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_GETPROTOBYNAME_R | ||||||
|  |   fi | ||||||
|  |   if test "$tmp_need_reentrant" = "no"; then | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_GETSERVBYPORT_R | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl This macro ensures that configuration tests done | ||||||
|  | dnl after this will execute with preprocessor symbol | ||||||
|  | dnl _REENTRANT defined. This macro also ensures that | ||||||
|  | dnl the generated config file defines NEED_REENTRANT | ||||||
|  | dnl and that in turn setup.h will define _REENTRANT. | ||||||
|  | dnl Internal macro for CARES_CONFIGURE_REENTRANT. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT], [ | ||||||
|  | AC_DEFINE(NEED_REENTRANT, 1, | ||||||
|  |   [Define to 1 if _REENTRANT preprocessor symbol must be defined.]) | ||||||
|  | cat >>confdefs.h <<_EOF | ||||||
|  | #ifndef _REENTRANT | ||||||
|  | #  define _REENTRANT | ||||||
|  | #endif | ||||||
|  | _EOF | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | dnl CARES_CONFIGURE_REENTRANT | ||||||
|  | dnl ------------------------------------------------- | ||||||
|  | dnl This first checks if the preprocessor _REENTRANT | ||||||
|  | dnl symbol is already defined. If it isn't currently | ||||||
|  | dnl defined a set of checks are performed to verify | ||||||
|  | dnl if its definition is required to make visible to | ||||||
|  | dnl the compiler a set of *_r functions. Finally, if | ||||||
|  | dnl _REENTRANT is already defined or needed it takes | ||||||
|  | dnl care of making adjustments necessary to ensure | ||||||
|  | dnl that it is defined equally for further configure | ||||||
|  | dnl tests and generated config file. | ||||||
|  |  | ||||||
|  | AC_DEFUN([CARES_CONFIGURE_REENTRANT], [ | ||||||
|  |   AC_PREREQ([2.50])dnl | ||||||
|  |   # | ||||||
|  |   AC_MSG_CHECKING([if _REENTRANT is already defined]) | ||||||
|  |   AC_COMPILE_IFELSE([ | ||||||
|  |     AC_LANG_PROGRAM([[ | ||||||
|  |     ]],[[ | ||||||
|  | #ifdef _REENTRANT | ||||||
|  |       int dummy=1; | ||||||
|  | #else | ||||||
|  |       force compilation error | ||||||
|  | #endif | ||||||
|  |     ]]) | ||||||
|  |   ],[ | ||||||
|  |     AC_MSG_RESULT([yes]) | ||||||
|  |     tmp_reentrant_initially_defined="yes" | ||||||
|  |   ],[ | ||||||
|  |     AC_MSG_RESULT([no]) | ||||||
|  |     tmp_reentrant_initially_defined="no" | ||||||
|  |   ]) | ||||||
|  |   # | ||||||
|  |   if test "$tmp_reentrant_initially_defined" = "no"; then | ||||||
|  |     AC_MSG_CHECKING([if _REENTRANT is actually needed]) | ||||||
|  |     CARES_CHECK_NEED_REENTRANT_FUNCTIONS_R | ||||||
|  |     if test "$tmp_need_reentrant" = "yes"; then | ||||||
|  |       AC_MSG_RESULT([yes]) | ||||||
|  |     else | ||||||
|  |       AC_MSG_RESULT([no]) | ||||||
|  |     fi | ||||||
|  |   fi | ||||||
|  |   # | ||||||
|  |   AC_MSG_CHECKING([if _REENTRANT is onwards defined]) | ||||||
|  |   if test "$tmp_reentrant_initially_defined" = "yes" || | ||||||
|  |     test "$tmp_need_reentrant" = "yes"; then | ||||||
|  |     CARES_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT | ||||||
|  |     AC_MSG_RESULT([yes]) | ||||||
|  |   else | ||||||
|  |     AC_MSG_RESULT([no]) | ||||||
|  |   fi | ||||||
|  |   # | ||||||
|  | ]) | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								ares/maketgz
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ares/maketgz
									
									
									
									
									
								
							| @@ -38,11 +38,11 @@ if(!-f "configure") { | |||||||
|     `./buildconf`; |     `./buildconf`; | ||||||
| } | } | ||||||
| print "adding $version in the configure.ac file\n"; | print "adding $version in the configure.ac file\n"; | ||||||
| `sed -e 's/AM_INIT_AUTOMAKE(c-ares, CVS)/AM_INIT_AUTOMAKE(c-ares, $version)/' < configure.ac > configure.ac-rel`; | `sed -e 's/AC_INIT.*/AC_INIT([c-ares], [$version],/' < configure.ac > configure.ac.dist`; | ||||||
|  |  | ||||||
| # now make a new configure script with this | # now make a new configure script with this | ||||||
| print "makes a new configure script\n"; | print "makes a new configure script\n"; | ||||||
| `autoconf configure.ac-rel >configure`; | `autoconf configure.ac.dist >configure`; | ||||||
|  |  | ||||||
| # now run this new configure to get a fine makefile | # now run this new configure to get a fine makefile | ||||||
| print "running configure\n"; | print "running configure\n"; | ||||||
| @@ -50,9 +50,11 @@ print "running configure\n"; | |||||||
|  |  | ||||||
| # now make the actual tarball | # now make the actual tarball | ||||||
| print "running make dist\n"; | print "running make dist\n"; | ||||||
| `make dist`; | `make dist VERSION=$version`; | ||||||
|  |  | ||||||
| print "removing temporary configure.ac file\n"; | print "removing temporary configure.ac file\n"; | ||||||
| `rm configure.ac-rel`; | `rm configure.ac.dist`; | ||||||
|  | print "removing temporary ares_version.h file\n"; | ||||||
|  | `rm ares_version.h.dist`; | ||||||
|  |  | ||||||
| print "NOTE: now cvs tag this release!\n"; | print "NOTE: now cvs tag this release!\n"; | ||||||
|   | |||||||
| @@ -7,17 +7,12 @@ | |||||||
|    port build */ |    port build */ | ||||||
|  |  | ||||||
| #ifndef NETWARE | #ifndef NETWARE | ||||||
| #ifndef __CYGWIN__ |  | ||||||
| #include <windows.h> |  | ||||||
| #endif |  | ||||||
| #include <process.h> /* for the _getpid() proto */ | #include <process.h> /* for the _getpid() proto */ | ||||||
| #endif  /* !NETWARE */ | #endif  /* !NETWARE */ | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
|  |  | ||||||
| #ifndef NETWARE | #ifndef NETWARE | ||||||
|  |  | ||||||
| #define MAXHOSTNAMELEN 256 |  | ||||||
|  |  | ||||||
| /* Structure for scatter/gather I/O.  */ | /* Structure for scatter/gather I/O.  */ | ||||||
| struct iovec | struct iovec | ||||||
| { | { | ||||||
| @@ -32,13 +27,6 @@ struct iovec | |||||||
| int ares_writev (SOCKET s, const struct iovec *vector, size_t count); | int ares_writev (SOCKET s, const struct iovec *vector, size_t count); | ||||||
| #define writev(s,vect,count)  ares_writev(s,vect,count) | #define writev(s,vect,count)  ares_writev(s,vect,count) | ||||||
|  |  | ||||||
| #ifndef HAVE_GETTIMEOFDAY |  | ||||||
| struct timezone { int dummy; }; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| int ares_gettimeofday(struct timeval *tv, struct timezone *tz); |  | ||||||
| #define gettimeofday(tv,tz) ares_gettimeofday(tv,tz) |  | ||||||
|  |  | ||||||
| #endif  /* !NETWARE */ | #endif  /* !NETWARE */ | ||||||
|  |  | ||||||
| #define NS_CMPRSFLGS  0xc0 | #define NS_CMPRSFLGS  0xc0 | ||||||
| @@ -149,6 +137,11 @@ typedef enum __ns_opcode { | |||||||
|  |  | ||||||
| #define T_CNAME                ns_t_cname | #define T_CNAME                ns_t_cname | ||||||
|  |  | ||||||
|  | #define NS_MAXDNAME   256     /* maximum domain name */ | ||||||
|  | #define MAXDNAME      NS_MAXDNAME | ||||||
|  |  | ||||||
|  | #define NS_MAXCDNAME  255     /* maximum compressed domain name */ | ||||||
|  | #define MAXCDNAME     NS_MAXCDNAME | ||||||
|  |  | ||||||
| #define NS_PACKETSZ   512     /* maximum packet size */ | #define NS_PACKETSZ   512     /* maximum packet size */ | ||||||
| #define PACKETSZ       NS_PACKETSZ | #define PACKETSZ       NS_PACKETSZ | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								ares/setup.h
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								ares/setup.h
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | |||||||
|  |  | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright (C) 2004 - 2007 by Daniel Stenberg et al | /* Copyright (C) 2004 - 2008 by Daniel Stenberg et al | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this software and its |  * Permission to use, copy, modify, and distribute this software and its | ||||||
|  * documentation for any purpose and without fee is hereby granted, provided |  * documentation for any purpose and without fee is hereby granted, provided | ||||||
| @@ -16,13 +16,11 @@ | |||||||
|  * without express or implied warranty. |  * without express or implied warranty. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #if !defined(WIN32) && defined(__WIN32__) | /* | ||||||
| /* Borland fix */ |  * Define WIN32 when build target is Win32 API | ||||||
| #define WIN32 |  */ | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if !defined(WIN32) && defined(_WIN32) | #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) | ||||||
| /* VS2005 on x64 fix */ |  | ||||||
| #define WIN32 | #define WIN32 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -41,6 +39,18 @@ | |||||||
|  |  | ||||||
| #endif /* HAVE_CONFIG_H */ | #endif /* HAVE_CONFIG_H */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Tru64 needs _REENTRANT set for a few function prototypes and | ||||||
|  |  * things to appear in the system header files. Unixware needs it | ||||||
|  |  * to build proper reentrant code. Others may also need it. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifdef NEED_REENTRANT | ||||||
|  | #  ifndef _REENTRANT | ||||||
|  | #    define _REENTRANT | ||||||
|  | #  endif | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Include header files for windows builds before redefining anything. |  * Include header files for windows builds before redefining anything. | ||||||
|  * Use this preproessor block only to include or exclude windows.h, |  * Use this preproessor block only to include or exclude windows.h, | ||||||
| @@ -97,10 +107,6 @@ | |||||||
| #define ssize_t int | #define ssize_t int | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef HAVE_WS2TCPIP_H |  | ||||||
| #define socklen_t int |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif /* HAVE_CONFIG_H */ | #endif /* HAVE_CONFIG_H */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
|  |  | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  |  | ||||||
| /* Copyright (C) 2004 - 2007 by Daniel Stenberg et al | /* Copyright (C) 2004 - 2008 by Daniel Stenberg et al | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this software and its |  * Permission to use, copy, modify, and distribute this software and its | ||||||
|  * documentation for any purpose and without fee is hereby granted, provided |  * documentation for any purpose and without fee is hereby granted, provided | ||||||
| @@ -91,6 +91,30 @@ struct timeval { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Windows build targets have socklen_t definition in | ||||||
|  |  * ws2tcpip.h but some versions of ws2tcpip.h do not | ||||||
|  |  * have the definition. It seems that when the socklen_t | ||||||
|  |  * definition is missing from ws2tcpip.h the definition | ||||||
|  |  * for INET_ADDRSTRLEN is also missing, and that when one | ||||||
|  |  * definition is present the other one also is available. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #if defined(WIN32) && !defined(HAVE_CONFIG_H) | ||||||
|  | #  if ( defined(_MSC_VER) && !defined(INET_ADDRSTRLEN) ) || \ | ||||||
|  |       (!defined(_MSC_VER) && !defined(HAVE_WS2TCPIP_H) ) | ||||||
|  | #    define socklen_t int | ||||||
|  | #  endif | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if defined(__minix) | ||||||
|  | /* Minix doesn't support recv on TCP sockets */ | ||||||
|  | #define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \ | ||||||
|  |                                    (RECV_TYPE_ARG2)(y), \ | ||||||
|  |                                    (RECV_TYPE_ARG3)(z)) | ||||||
|  |  | ||||||
|  | #elif defined(HAVE_RECV) | ||||||
| /* | /* | ||||||
|  * The definitions for the return type and arguments types |  * The definitions for the return type and arguments types | ||||||
|  * of functions recv() and send() belong and come from the |  * of functions recv() and send() belong and come from the | ||||||
| @@ -113,7 +137,6 @@ struct timeval { | |||||||
|  * SEND_TYPE_RETV must also be defined. |  * SEND_TYPE_RETV must also be defined. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifdef HAVE_RECV |  | ||||||
| #if !defined(RECV_TYPE_ARG1) || \ | #if !defined(RECV_TYPE_ARG1) || \ | ||||||
|     !defined(RECV_TYPE_ARG2) || \ |     !defined(RECV_TYPE_ARG2) || \ | ||||||
|     !defined(RECV_TYPE_ARG3) || \ |     !defined(RECV_TYPE_ARG3) || \ | ||||||
| @@ -136,7 +159,14 @@ struct timeval { | |||||||
| #endif | #endif | ||||||
| #endif /* HAVE_RECV */ | #endif /* HAVE_RECV */ | ||||||
|  |  | ||||||
| #ifdef HAVE_SEND |  | ||||||
|  | #if defined(__minix) | ||||||
|  | /* Minix doesn't support send on TCP sockets */ | ||||||
|  | #define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \ | ||||||
|  |                                     (SEND_TYPE_ARG2)(y), \ | ||||||
|  |                                     (SEND_TYPE_ARG3)(z)) | ||||||
|  |  | ||||||
|  | #elif defined(HAVE_SEND) | ||||||
| #if !defined(SEND_TYPE_ARG1) || \ | #if !defined(SEND_TYPE_ARG1) || \ | ||||||
|     !defined(SEND_QUAL_ARG2) || \ |     !defined(SEND_QUAL_ARG2) || \ | ||||||
|     !defined(SEND_TYPE_ARG2) || \ |     !defined(SEND_TYPE_ARG2) || \ | ||||||
| @@ -161,6 +191,46 @@ struct timeval { | |||||||
| #endif /* HAVE_SEND */ | #endif /* HAVE_SEND */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | #if defined(HAVE_RECVFROM) | ||||||
|  | /* | ||||||
|  |  * Currently recvfrom is only used on udp sockets. | ||||||
|  |  */ | ||||||
|  | #if !defined(RECVFROM_TYPE_ARG1) || \ | ||||||
|  |     !defined(RECVFROM_TYPE_ARG2) || \ | ||||||
|  |     !defined(RECVFROM_TYPE_ARG3) || \ | ||||||
|  |     !defined(RECVFROM_TYPE_ARG4) || \ | ||||||
|  |     !defined(RECVFROM_TYPE_ARG5) || \ | ||||||
|  |     !defined(RECVFROM_TYPE_ARG6) || \ | ||||||
|  |     !defined(RECVFROM_TYPE_RETV) | ||||||
|  |   /* */ | ||||||
|  |   Error Missing_definition_of_return_and_arguments_types_of_recvfrom | ||||||
|  |   /* */ | ||||||
|  | #else | ||||||
|  | #define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1)  (s),  \ | ||||||
|  |                                                  (RECVFROM_TYPE_ARG2 *)(b),  \ | ||||||
|  |                                                  (RECVFROM_TYPE_ARG3)  (bl), \ | ||||||
|  |                                                  (RECVFROM_TYPE_ARG4)  (0),  \ | ||||||
|  |                                                  (RECVFROM_TYPE_ARG5 *)(f),  \ | ||||||
|  |                                                  (RECVFROM_TYPE_ARG6 *)(fl)) | ||||||
|  | #endif | ||||||
|  | #else /* HAVE_RECVFROM */ | ||||||
|  | #ifndef sreadfrom | ||||||
|  |   /* */ | ||||||
|  |   Error Missing_definition_of_macro_sreadfrom | ||||||
|  |   /* */ | ||||||
|  | #endif | ||||||
|  | #endif /* HAVE_RECVFROM */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef RECVFROM_TYPE_ARG6_IS_VOID | ||||||
|  | #  define RECVFROM_ARG6_T int | ||||||
|  | #else | ||||||
|  | #  define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6 | ||||||
|  | #endif | ||||||
|  | #endif /* if 0 */ | ||||||
|  |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Uppercase macro versions of ANSI/ISO is*() functions/macros which |  * Uppercase macro versions of ANSI/ISO is*() functions/macros which | ||||||
|  * avoid negative number inputs with argument byte codes > 127. |  * avoid negative number inputs with argument byte codes > 127. | ||||||
| @@ -358,5 +428,96 @@ typedef int sig_atomic_t; | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * We use this ZERO_NULL to avoid picky compiler warnings, | ||||||
|  |  * when assigning a NULL pointer to a function pointer var. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #define ZERO_NULL 0 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if defined (__LP64__) && defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED) | ||||||
|  | #include <sys/socket.h> | ||||||
|  | /* HP-UX has this oddity where it features a few functions that don't work | ||||||
|  |    with socklen_t so we need to convert to ints | ||||||
|  |  | ||||||
|  |    This is due to socklen_t being a 64bit int under 64bit ABI, but the | ||||||
|  |    pre-xopen (default) interfaces require an int, which is 32bits. | ||||||
|  |  | ||||||
|  |    Therefore, Anytime socklen_t is passed by pointer, the libc function | ||||||
|  |    truncates the 64bit socklen_t value by treating it as a 32bit value. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    Note that some socket calls are allowed to have a NULL pointer for | ||||||
|  |    the socklen arg. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | inline static int Curl_hp_getsockname(int s, struct sockaddr *name, | ||||||
|  |                                       socklen_t *namelen) | ||||||
|  | { | ||||||
|  |   int rc; | ||||||
|  |   if(namelen) { | ||||||
|  |      int len = *namelen; | ||||||
|  |      rc = getsockname(s, name, &len); | ||||||
|  |      *namelen = len; | ||||||
|  |    } | ||||||
|  |   else | ||||||
|  |      rc = getsockname(s, name, 0); | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline static int Curl_hp_getsockopt(int  s, int level, int optname, | ||||||
|  |                                      void *optval, socklen_t *optlen) | ||||||
|  | { | ||||||
|  |   int rc; | ||||||
|  |   if(optlen) { | ||||||
|  |     int len = *optlen; | ||||||
|  |     rc = getsockopt(s, level, optname, optval, &len); | ||||||
|  |     *optlen = len; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |     rc = getsockopt(s, level, optname, optval, 0); | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline static int Curl_hp_accept(int sockfd, struct sockaddr *addr, | ||||||
|  |                                  socklen_t *addrlen) | ||||||
|  | { | ||||||
|  |   int rc; | ||||||
|  |   if(addrlen) { | ||||||
|  |      int len = *addrlen; | ||||||
|  |      rc = accept(sockfd, addr, &len); | ||||||
|  |      *addrlen = len; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |      rc = accept(sockfd, addr, 0); | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline static ssize_t Curl_hp_recvfrom(int s, void *buf, size_t len, int flags, | ||||||
|  |                                        struct sockaddr *from, | ||||||
|  |                                        socklen_t *fromlen) | ||||||
|  | { | ||||||
|  |   ssize_t rc; | ||||||
|  |   if(fromlen) { | ||||||
|  |     int fromlen32 = *fromlen; | ||||||
|  |     rc = recvfrom(s, buf, len, flags, from, &fromlen32); | ||||||
|  |     *fromlen = fromlen32; | ||||||
|  |   } | ||||||
|  |   else { | ||||||
|  |     rc = recvfrom(s, buf, len, flags, from, 0); | ||||||
|  |   } | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define getsockname(a,b,c) Curl_hp_getsockname((a),(b),(c)) | ||||||
|  | #define getsockopt(a,b,c,d,e) Curl_hp_getsockopt((a),(b),(c),(d),(e)) | ||||||
|  | #define accept(a,b,c) Curl_hp_accept((a),(b),(c)) | ||||||
|  | #define recvfrom(a,b,c,d,e,f) Curl_hp_recvfrom((a),(b),(c),(d),(e),(f)) | ||||||
|  |  | ||||||
|  | #endif /* HPUX work-around */ | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif /* __SETUP_ONCE_H */ | #endif /* __SETUP_ONCE_H */ | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								ares/vc/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								ares/vc/.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | vc.ncb | ||||||
|  | vc.opt | ||||||
							
								
								
									
										3
									
								
								ares/vc/acountry/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ares/vc/acountry/.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | acountry.dep | ||||||
|  | acountry.mak | ||||||
|  | acountry.plg | ||||||
							
								
								
									
										110
									
								
								ares/vc/acountry/acountry.dsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								ares/vc/acountry/acountry.dsp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | # Microsoft Developer Studio Project File - Name="acountry" - Package Owner=<4> | ||||||
|  | # Microsoft Developer Studio Generated Build File, Format Version 6.00 | ||||||
|  | # ** DO NOT EDIT ** | ||||||
|  |  | ||||||
|  | # TARGTYPE "Win32 (x86) Console Application" 0x0103 | ||||||
|  |  | ||||||
|  | CFG=acountry - Win32 Debug | ||||||
|  | !MESSAGE This is not a valid makefile. To build this project using NMAKE, | ||||||
|  | !MESSAGE use the Export Makefile command and run | ||||||
|  | !MESSAGE  | ||||||
|  | !MESSAGE NMAKE /f "acountry.mak". | ||||||
|  | !MESSAGE  | ||||||
|  | !MESSAGE You can specify a configuration when running NMAKE | ||||||
|  | !MESSAGE by defining the macro CFG on the command line. For example: | ||||||
|  | !MESSAGE  | ||||||
|  | !MESSAGE NMAKE /f "acountry.mak" CFG="acountry - Win32 Debug" | ||||||
|  | !MESSAGE  | ||||||
|  | !MESSAGE Possible choices for configuration are: | ||||||
|  | !MESSAGE  | ||||||
|  | !MESSAGE "acountry - Win32 Release" (based on "Win32 (x86) Console Application") | ||||||
|  | !MESSAGE "acountry - Win32 Debug" (based on "Win32 (x86) Console Application") | ||||||
|  | !MESSAGE  | ||||||
|  |  | ||||||
|  | # Begin Project | ||||||
|  | # PROP AllowPerConfigDependencies 0 | ||||||
|  | # PROP Scc_ProjName "" | ||||||
|  | # PROP Scc_LocalPath "" | ||||||
|  | CPP=cl.exe | ||||||
|  | RSC=rc.exe | ||||||
|  |  | ||||||
|  | !IF  "$(CFG)" == "acountry - Win32 Release" | ||||||
|  |  | ||||||
|  | # PROP BASE Use_MFC 0 | ||||||
|  | # PROP BASE Use_Debug_Libraries 0 | ||||||
|  | # PROP BASE Output_Dir "Release" | ||||||
|  | # PROP BASE Intermediate_Dir "Release" | ||||||
|  | # PROP BASE Target_Dir "" | ||||||
|  | # PROP Use_MFC 0 | ||||||
|  | # PROP Use_Debug_Libraries 0 | ||||||
|  | # PROP Output_Dir "Release" | ||||||
|  | # PROP Intermediate_Dir "Release" | ||||||
|  | # PROP Ignore_Export_Lib 0 | ||||||
|  | # PROP Target_Dir "" | ||||||
|  | # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c | ||||||
|  | # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c | ||||||
|  | # ADD BASE RSC /l 0x409 /d "NDEBUG" | ||||||
|  | # ADD RSC /l 0x409 /d "NDEBUG" | ||||||
|  | BSC32=bscmake.exe | ||||||
|  | # ADD BASE BSC32 /nologo | ||||||
|  | # ADD BSC32 /nologo | ||||||
|  | LINK32=link.exe | ||||||
|  | # ADD BASE LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | ||||||
|  | # ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | ||||||
|  |  | ||||||
|  | !ELSEIF  "$(CFG)" == "acountry - Win32 Debug" | ||||||
|  |  | ||||||
|  | # PROP BASE Use_MFC 0 | ||||||
|  | # PROP BASE Use_Debug_Libraries 1 | ||||||
|  | # PROP BASE Output_Dir "Debug" | ||||||
|  | # PROP BASE Intermediate_Dir "Debug" | ||||||
|  | # PROP BASE Target_Dir "" | ||||||
|  | # PROP Use_MFC 0 | ||||||
|  | # PROP Use_Debug_Libraries 1 | ||||||
|  | # PROP Output_Dir "Debug" | ||||||
|  | # PROP Intermediate_Dir "Debug" | ||||||
|  | # PROP Ignore_Export_Lib 0 | ||||||
|  | # PROP Target_Dir "" | ||||||
|  | # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c | ||||||
|  | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c | ||||||
|  | # ADD BASE RSC /l 0x409 /d "_DEBUG" | ||||||
|  | # ADD RSC /l 0x409 /d "_DEBUG" | ||||||
|  | BSC32=bscmake.exe | ||||||
|  | # ADD BASE BSC32 /nologo | ||||||
|  | # ADD BSC32 /nologo | ||||||
|  | LINK32=link.exe | ||||||
|  | # ADD BASE LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | ||||||
|  | # ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | ||||||
|  |  | ||||||
|  | !ENDIF  | ||||||
|  |  | ||||||
|  | # Begin Target | ||||||
|  |  | ||||||
|  | # Name "acountry - Win32 Release" | ||||||
|  | # Name "acountry - Win32 Debug" | ||||||
|  | # Begin Group "Source Files" | ||||||
|  |  | ||||||
|  | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\acountry.c | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\ares_getopt.c | ||||||
|  | # End Source File | ||||||
|  | # End Group | ||||||
|  | # Begin Group "Header Files" | ||||||
|  |  | ||||||
|  | # PROP Default_Filter "h;hpp;hxx;hm;inl" | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\ares_getopt.h | ||||||
|  | # End Source File | ||||||
|  | # End Group | ||||||
|  | # Begin Group "Resource Files" | ||||||
|  |  | ||||||
|  | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" | ||||||
|  | # End Group | ||||||
|  | # End Target | ||||||
|  | # End Project | ||||||
							
								
								
									
										3
									
								
								ares/vc/adig/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ares/vc/adig/.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | adig.dep | ||||||
|  | adig.mak | ||||||
|  | adig.plg | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| # Microsoft Developer Studio Generated Dependency File, included by adig.mak |  | ||||||
|  |  | ||||||
| @@ -41,16 +41,16 @@ RSC=rc.exe | |||||||
| # PROP Intermediate_Dir "Release" | # PROP Intermediate_Dir "Release" | ||||||
| # PROP Ignore_Export_Lib 0 | # PROP Ignore_Export_Lib 0 | ||||||
| # PROP Target_Dir "" | # PROP Target_Dir "" | ||||||
| # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c | ||||||
| # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c | ||||||
| # ADD BASE RSC /l 0x409 /d "NDEBUG" | # ADD BASE RSC /l 0x409 /d "NDEBUG" | ||||||
| # ADD RSC /l 0x409 /d "NDEBUG" | # ADD RSC /l 0x409 /d "NDEBUG" | ||||||
| BSC32=bscmake.exe | BSC32=bscmake.exe | ||||||
| # ADD BASE BSC32 /nologo | # ADD BASE BSC32 /nologo | ||||||
| # ADD BSC32 /nologo | # ADD BSC32 /nologo | ||||||
| LINK32=link.exe | LINK32=link.exe | ||||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 | # ADD BASE LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | ||||||
| # ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | # ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | ||||||
|  |  | ||||||
| !ELSEIF  "$(CFG)" == "adig - Win32 Debug" | !ELSEIF  "$(CFG)" == "adig - Win32 Debug" | ||||||
|  |  | ||||||
| @@ -65,16 +65,16 @@ LINK32=link.exe | |||||||
| # PROP Intermediate_Dir "Debug" | # PROP Intermediate_Dir "Debug" | ||||||
| # PROP Ignore_Export_Lib 0 | # PROP Ignore_Export_Lib 0 | ||||||
| # PROP Target_Dir "" | # PROP Target_Dir "" | ||||||
| # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c | # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c | ||||||
| # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c | ||||||
| # ADD BASE RSC /l 0x409 /d "_DEBUG" | # ADD BASE RSC /l 0x409 /d "_DEBUG" | ||||||
| # ADD RSC /l 0x409 /d "_DEBUG" | # ADD RSC /l 0x409 /d "_DEBUG" | ||||||
| BSC32=bscmake.exe | BSC32=bscmake.exe | ||||||
| # ADD BASE BSC32 /nologo | # ADD BASE BSC32 /nologo | ||||||
| # ADD BSC32 /nologo | # ADD BSC32 /nologo | ||||||
| LINK32=link.exe | LINK32=link.exe | ||||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept | # ADD BASE LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | ||||||
| # ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | # ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | ||||||
|  |  | ||||||
| !ENDIF  | !ENDIF  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								ares/vc/ahost/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ares/vc/ahost/.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ahost.dep | ||||||
|  | ahost.mak | ||||||
|  | ahost.plg | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| # Microsoft Developer Studio Generated Dependency File, included by ahost.mak |  | ||||||
|  |  | ||||||
| @@ -39,17 +39,18 @@ RSC=rc.exe | |||||||
| # PROP Use_Debug_Libraries 0 | # PROP Use_Debug_Libraries 0 | ||||||
| # PROP Output_Dir "Release" | # PROP Output_Dir "Release" | ||||||
| # PROP Intermediate_Dir "Release" | # PROP Intermediate_Dir "Release" | ||||||
|  | # PROP Ignore_Export_Lib 0 | ||||||
| # PROP Target_Dir "" | # PROP Target_Dir "" | ||||||
| # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c | ||||||
| # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c | ||||||
| # ADD BASE RSC /l 0x409 /d "NDEBUG" | # ADD BASE RSC /l 0x409 /d "NDEBUG" | ||||||
| # ADD RSC /l 0x409 /d "NDEBUG" | # ADD RSC /l 0x409 /d "NDEBUG" | ||||||
| BSC32=bscmake.exe | BSC32=bscmake.exe | ||||||
| # ADD BASE BSC32 /nologo | # ADD BASE BSC32 /nologo | ||||||
| # ADD BSC32 /nologo | # ADD BSC32 /nologo | ||||||
| LINK32=link.exe | LINK32=link.exe | ||||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 | # ADD BASE LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | ||||||
| # ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | # ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" | ||||||
|  |  | ||||||
| !ELSEIF  "$(CFG)" == "ahost - Win32 Debug" | !ELSEIF  "$(CFG)" == "ahost - Win32 Debug" | ||||||
|  |  | ||||||
| @@ -62,17 +63,18 @@ LINK32=link.exe | |||||||
| # PROP Use_Debug_Libraries 1 | # PROP Use_Debug_Libraries 1 | ||||||
| # PROP Output_Dir "Debug" | # PROP Output_Dir "Debug" | ||||||
| # PROP Intermediate_Dir "Debug" | # PROP Intermediate_Dir "Debug" | ||||||
|  | # PROP Ignore_Export_Lib 0 | ||||||
| # PROP Target_Dir "" | # PROP Target_Dir "" | ||||||
| # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c | # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c | ||||||
| # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c | ||||||
| # ADD BASE RSC /l 0x409 /d "_DEBUG" | # ADD BASE RSC /l 0x409 /d "_DEBUG" | ||||||
| # ADD RSC /l 0x409 /d "_DEBUG" | # ADD RSC /l 0x409 /d "_DEBUG" | ||||||
| BSC32=bscmake.exe | BSC32=bscmake.exe | ||||||
| # ADD BASE BSC32 /nologo | # ADD BASE BSC32 /nologo | ||||||
| # ADD BSC32 /nologo | # ADD BSC32 /nologo | ||||||
| LINK32=link.exe | LINK32=link.exe | ||||||
| # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept | # ADD BASE LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | ||||||
| # ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | # ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" | ||||||
|  |  | ||||||
| !ENDIF  | !ENDIF  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								ares/vc/areslib/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ares/vc/areslib/.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | areslib.dep | ||||||
|  | areslib.mak | ||||||
|  | areslib.plg | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| # Microsoft Developer Studio Generated Dependency File, included by areslib.mak |  | ||||||
|  |  | ||||||
| @@ -40,8 +40,8 @@ RSC=rc.exe | |||||||
| # PROP Output_Dir "Release" | # PROP Output_Dir "Release" | ||||||
| # PROP Intermediate_Dir "Release" | # PROP Intermediate_Dir "Release" | ||||||
| # PROP Target_Dir "" | # PROP Target_Dir "" | ||||||
| # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c | # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c | ||||||
| # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c | # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c | ||||||
| # ADD BASE RSC /l 0x409 /d "NDEBUG" | # ADD BASE RSC /l 0x409 /d "NDEBUG" | ||||||
| # ADD RSC /l 0x409 /d "NDEBUG" | # ADD RSC /l 0x409 /d "NDEBUG" | ||||||
| BSC32=bscmake.exe | BSC32=bscmake.exe | ||||||
| @@ -63,8 +63,8 @@ LIB32=link.exe -lib | |||||||
| # PROP Output_Dir "Debug" | # PROP Output_Dir "Debug" | ||||||
| # PROP Intermediate_Dir "Debug" | # PROP Intermediate_Dir "Debug" | ||||||
| # PROP Target_Dir "" | # PROP Target_Dir "" | ||||||
| # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c | # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c | ||||||
| # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\.." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c | ||||||
| # ADD BASE RSC /l 0x409 /d "_DEBUG" | # ADD BASE RSC /l 0x409 /d "_DEBUG" | ||||||
| # ADD RSC /l 0x409 /d "_DEBUG" | # ADD RSC /l 0x409 /d "_DEBUG" | ||||||
| BSC32=bscmake.exe | BSC32=bscmake.exe | ||||||
| @@ -97,6 +97,10 @@ SOURCE=..\..\ares__read_line.c | |||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\ares__timeval.c | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
| SOURCE=..\..\ares_cancel.c | SOURCE=..\..\ares_cancel.c | ||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
| @@ -109,6 +113,10 @@ SOURCE=..\..\ares_expand_name.c | |||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\ares_expand_string.c | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
| SOURCE=..\..\ares_fds.c | SOURCE=..\..\ares_fds.c | ||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
| @@ -137,6 +145,10 @@ SOURCE=..\..\ares_init.c | |||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\ares_llist.c | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
| SOURCE=..\..\ares_mkquery.c | SOURCE=..\..\ares_mkquery.c | ||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
| @@ -213,6 +225,10 @@ SOURCE=..\..\ares_ipv6.h | |||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|  |  | ||||||
|  | SOURCE=..\..\ares_llist.h | ||||||
|  | # End Source File | ||||||
|  | # Begin Source File | ||||||
|  |  | ||||||
| SOURCE=..\..\ares_private.h | SOURCE=..\..\ares_private.h | ||||||
| # End Source File | # End Source File | ||||||
| # Begin Source File | # Begin Source File | ||||||
|   | |||||||
| @@ -3,6 +3,21 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 | |||||||
|  |  | ||||||
| ############################################################################### | ############################################################################### | ||||||
|  |  | ||||||
|  | Project: "acountry"=".\acountry\acountry.dsp" - Package Owner=<4> | ||||||
|  |  | ||||||
|  | Package=<5> | ||||||
|  | {{{ | ||||||
|  | }}} | ||||||
|  |  | ||||||
|  | Package=<4> | ||||||
|  | {{{ | ||||||
|  |     Begin Project Dependency | ||||||
|  |     Project_Dep_Name areslib | ||||||
|  |     End Project Dependency | ||||||
|  | }}} | ||||||
|  |  | ||||||
|  | ############################################################################### | ||||||
|  |  | ||||||
| Project: "adig"=".\adig\adig.dsp" - Package Owner=<4> | Project: "adig"=".\adig\adig.dsp" - Package Owner=<4> | ||||||
|  |  | ||||||
| Package=<5> | Package=<5> | ||||||
|   | |||||||
| @@ -55,37 +55,6 @@ ares_strcasecmp(const char *a, const char *b) | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Number of micro-seconds between the beginning of the Windows epoch |  | ||||||
|  * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970). |  | ||||||
|  */ |  | ||||||
| #if defined(_MSC_VER) || defined(__WATCOMC__) |  | ||||||
| #define EPOCH_FILETIME 11644473600000000Ui64 |  | ||||||
| #else |  | ||||||
| #define EPOCH_FILETIME 11644473600000000ULL |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| int |  | ||||||
| ares_gettimeofday(struct timeval *tv, struct timezone *tz) |  | ||||||
| { |  | ||||||
|     FILETIME        ft; |  | ||||||
|     LARGE_INTEGER   li; |  | ||||||
|     __int64         t; |  | ||||||
|  |  | ||||||
|     if (tv) |  | ||||||
|     { |  | ||||||
|         GetSystemTimeAsFileTime(&ft); |  | ||||||
|         li.LowPart  = ft.dwLowDateTime; |  | ||||||
|         li.HighPart = ft.dwHighDateTime; |  | ||||||
|         t  = li.QuadPart / 10;   /* In micro-second intervals */ |  | ||||||
|         t -= EPOCH_FILETIME;     /* Offset to the Epoch time */ |  | ||||||
|         tv->tv_sec  = (long)(t / 1000000); |  | ||||||
|         tv->tv_usec = (long)(t % 1000000); |  | ||||||
|     } |  | ||||||
|     (void) tz; |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int | int | ||||||
| ares_writev (ares_socket_t s, const struct iovec *vector, size_t count) | ares_writev (ares_socket_t s, const struct iovec *vector, size_t count) | ||||||
| { | { | ||||||
|   | |||||||
							
								
								
									
										104
									
								
								buildconf
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								buildconf
									
									
									
									
									
								
							| @@ -6,7 +6,7 @@ | |||||||
| #                            | (__| |_| |  _ <| |___ | #                            | (__| |_| |  _ <| |___ | ||||||
| #                             \___|\___/|_| \_\_____| | #                             \___|\___/|_| \_\_____| | ||||||
| # | # | ||||||
| # Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al. | # Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
| # | # | ||||||
| # This software is licensed as described in the file COPYING, which | # This software is licensed as described in the file COPYING, which | ||||||
| # you should have received as part of this distribution. The terms | # you should have received as part of this distribution. The terms | ||||||
| @@ -27,22 +27,57 @@ die(){ | |||||||
| 	exit | 	exit | ||||||
| } | } | ||||||
|  |  | ||||||
| # this works as 'which' but we use a different name to make it more obvious we | #-------------------------------------------------------------------------- | ||||||
| # aren't using 'which'! ;-) | # findtool works as 'which' but we use a different name to make it more | ||||||
|  | # obvious we aren't using 'which'! ;-) | ||||||
|  | # | ||||||
| findtool(){ | findtool(){ | ||||||
|   file="$1" |   file="$1" | ||||||
|  |  | ||||||
|   IFS=":" |   old_IFS=$IFS; IFS=':' | ||||||
|   for path in $PATH |   for path in $PATH | ||||||
|   do |   do | ||||||
|  |     IFS=$old_IFS | ||||||
|     # echo "checks for $file in $path" >&2 |     # echo "checks for $file in $path" >&2 | ||||||
|     if test -f "$path/$file"; then |     if test -f "$path/$file"; then | ||||||
|       echo "$path/$file" |       echo "$path/$file" | ||||||
|       return |       return | ||||||
|     fi |     fi | ||||||
|   done |   done | ||||||
|  |   IFS=$old_IFS | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #-------------------------------------------------------------------------- | ||||||
|  | # removethis() removes all files and subdirectories with the given name, | ||||||
|  | # inside and below the current subdirectory at invocation time. | ||||||
|  | # | ||||||
|  | removethis(){ | ||||||
|  |   if test "$#" = "1"; then | ||||||
|  |     find . -depth -name $1 -print > buildconf.tmp.$$ | ||||||
|  |     while read fdname | ||||||
|  |     do | ||||||
|  |       if test -f "$fdname"; then | ||||||
|  |         rm -f "$fdname" | ||||||
|  |       elif test -d "$fdname"; then | ||||||
|  |         rm -f -r "$fdname" | ||||||
|  |       fi | ||||||
|  |     done < buildconf.tmp.$$ | ||||||
|  |     rm -f buildconf.tmp.$$ | ||||||
|  |   fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #-------------------------------------------------------------------------- | ||||||
|  | # Ensure that buildconf runs from the subdirectory where configure.ac lives | ||||||
|  | # | ||||||
|  | if test ! -f configure.ac || | ||||||
|  |   test ! -f src/main.c || | ||||||
|  |   test ! -f lib/urldata.h || | ||||||
|  |   test ! -f include/curl/curl.h; then | ||||||
|  |   echo "Can not run buildconf from outside of curl's source subdirectory!" | ||||||
|  |   echo "Change to the subdirectory where buildconf is found, and try again." | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| #-------------------------------------------------------------------------- | #-------------------------------------------------------------------------- | ||||||
| # autoconf 2.57 or newer | # autoconf 2.57 or newer | ||||||
| # | # | ||||||
| @@ -65,6 +100,18 @@ fi | |||||||
|  |  | ||||||
| echo "buildconf: autoconf version $ac_version (ok)" | echo "buildconf: autoconf version $ac_version (ok)" | ||||||
|  |  | ||||||
|  | am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'` | ||||||
|  | if test -z "$am4te_version"; then | ||||||
|  |   echo "buildconf: autom4te not found. Weird autoconf installation!" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  | if test "$am4te_version" = "$ac_version"; then | ||||||
|  |   echo "buildconf: autom4te version $am4te_version (ok)" | ||||||
|  | else | ||||||
|  |   echo "buildconf: autom4te version $am4te_version (ERROR: does not match autoconf version)" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| #-------------------------------------------------------------------------- | #-------------------------------------------------------------------------- | ||||||
| # autoheader 2.50 or newer | # autoheader 2.50 or newer | ||||||
| # | # | ||||||
| @@ -108,12 +155,16 @@ fi | |||||||
|  |  | ||||||
| echo "buildconf: automake version $am_version (ok)" | echo "buildconf: automake version $am_version (ok)" | ||||||
|  |  | ||||||
| ac=`findtool ${ACLOCAL:-aclocal}` | acloc_version=`${ACLOCAL:-aclocal} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'` | ||||||
| if test -z "$ac"; then | if test -z "$acloc_version"; then | ||||||
|   echo "buildconf: aclocal not found. Weird automake installation!" |   echo "buildconf: aclocal not found. Weird automake installation!" | ||||||
|   exit 1 |   exit 1 | ||||||
|  | fi | ||||||
|  | if test "$acloc_version" = "$am_version"; then | ||||||
|  |   echo "buildconf: aclocal version $acloc_version (ok)" | ||||||
| else | else | ||||||
|   echo "buildconf: aclocal found" |   echo "buildconf: aclocal version $acloc_version (ERROR: does not match automake version)" | ||||||
|  |   exit 1 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| #-------------------------------------------------------------------------- | #-------------------------------------------------------------------------- | ||||||
| @@ -202,14 +253,46 @@ fi | |||||||
| # | # | ||||||
| PERL=`findtool ${PERL:-perl}` | PERL=`findtool ${PERL:-perl}` | ||||||
|  |  | ||||||
| # ------------------------------------------------------------ | #-------------------------------------------------------------------------- | ||||||
|  | # Remove files generated on previous buildconf/configure run. | ||||||
|  | # | ||||||
|  | for fname in .deps \ | ||||||
|  |     Makefile.in \ | ||||||
|  |     aclocal.m4 \ | ||||||
|  |     aclocal.m4.bak \ | ||||||
|  |     autom4te.cache \ | ||||||
|  |     compile \ | ||||||
|  |     config.guess \ | ||||||
|  |     config.h \ | ||||||
|  |     config.h.in \ | ||||||
|  |     config.log \ | ||||||
|  |     config.status \ | ||||||
|  |     config.sub \ | ||||||
|  |     configure \ | ||||||
|  |     curl-config \ | ||||||
|  |     curlbuild.h \ | ||||||
|  |     depcomp \ | ||||||
|  |     libcares.pc \ | ||||||
|  |     libcurl.pc \ | ||||||
|  |     libtool \ | ||||||
|  |     libtool.m4 \ | ||||||
|  |     ltmain.sh \ | ||||||
|  |     stamp-h1 \ | ||||||
|  |     stamp-h2 \ | ||||||
|  |     stamp-h3 ; do | ||||||
|  |   removethis "$fname" | ||||||
|  | done | ||||||
|  |  | ||||||
|  | #-------------------------------------------------------------------------- | ||||||
| # run the correct scripts now | # run the correct scripts now | ||||||
|  | # | ||||||
|  |  | ||||||
| echo "buildconf: running libtoolize" | echo "buildconf: running libtoolize" | ||||||
| $libtoolize --copy --automake --force || die "The libtoolize command failed" | $libtoolize --copy --automake --force || die "The libtoolize command failed" | ||||||
|  |  | ||||||
| echo "buildconf: running aclocal" | echo "buildconf: running aclocal" | ||||||
| ${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed" | ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "The aclocal command line failed" | ||||||
|  |  | ||||||
| if test -n "$PERL"; then | if test -n "$PERL"; then | ||||||
|   echo "buildconf: running aclocal hack to convert all mv to mv -f" |   echo "buildconf: running aclocal hack to convert all mv to mv -f" | ||||||
|   $PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 |   $PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 | ||||||
| @@ -217,10 +300,13 @@ else | |||||||
|   echo "buildconf: perl not found" |   echo "buildconf: perl not found" | ||||||
|   exit 1 |   exit 1 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| echo "buildconf: running autoheader" | echo "buildconf: running autoheader" | ||||||
| ${AUTOHEADER:-autoheader} || die "The autoheader command failed" | ${AUTOHEADER:-autoheader} || die "The autoheader command failed" | ||||||
|  |  | ||||||
| echo "buildconf: cp lib/config.h.in src/config.h.in" | echo "buildconf: cp lib/config.h.in src/config.h.in" | ||||||
| cp lib/config.h.in src/config.h.in | cp lib/config.h.in src/config.h.in | ||||||
|  |  | ||||||
| echo "buildconf: running autoconf" | echo "buildconf: running autoconf" | ||||||
| ${AUTOCONF:-autoconf}     || die "The autoconf command failed" | ${AUTOCONF:-autoconf}     || die "The autoconf command failed" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,11 +3,11 @@ REM set up a CVS tree to build when there's no autotools | |||||||
| REM $Revision$ | REM $Revision$ | ||||||
| REM $Date$ | REM $Date$ | ||||||
|  |  | ||||||
| REM create ca-bundle.h |  | ||||||
| echo /* This file is generated automatically */ >lib\ca-bundle.h |  | ||||||
|  |  | ||||||
| REM create hugehelp.c | REM create hugehelp.c | ||||||
| copy src\hugehelp.c.cvs src\hugehelp.c | copy src\hugehelp.c.cvs src\hugehelp.c | ||||||
|  |  | ||||||
| REM create Makefile | REM create Makefile | ||||||
| copy Makefile.dist Makefile | copy Makefile.dist Makefile | ||||||
|  |  | ||||||
|  | REM create curlbuild.h | ||||||
|  | copy include\curl\curlbuild.h.dist include\curl\curlbuild.h | ||||||
|   | |||||||
							
								
								
									
										889
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										889
									
								
								configure.ac
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -6,7 +6,7 @@ | |||||||
| #                            | (__| |_| |  _ <| |___ | #                            | (__| |_| |  _ <| |___ | ||||||
| #                             \___|\___/|_| \_\_____| | #                             \___|\___/|_| \_\_____| | ||||||
| # | # | ||||||
| # Copyright (C) 2001 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. | # Copyright (C) 2001 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. | ||||||
| # | # | ||||||
| # This software is licensed as described in the file COPYING, which | # This software is licensed as described in the file COPYING, which | ||||||
| # you should have received as part of this distribution. The terms | # you should have received as part of this distribution. The terms | ||||||
| @@ -41,10 +41,11 @@ Available values for OPTION include: | |||||||
|   --cflags    pre-processor and compiler flags |   --cflags    pre-processor and compiler flags | ||||||
|   --checkfor [version] check for (lib)curl of the specified version |   --checkfor [version] check for (lib)curl of the specified version | ||||||
|   --features  newline separated list of enabled features |   --features  newline separated list of enabled features | ||||||
|   --protocols newline separated list of enabled protocols |  | ||||||
|   --help      display this help and exit |   --help      display this help and exit | ||||||
|   --libs      library linking information |   --libs      library linking information | ||||||
|   --prefix    curl install prefix |   --prefix    curl install prefix | ||||||
|  |   --protocols newline separated list of enabled protocols | ||||||
|  |   --static-libs static libcurl library linking information | ||||||
|   --version   output version information |   --version   output version information | ||||||
|   --vernum    output the version information as a number (hexadecimal) |   --vernum    output the version information as a number (hexadecimal) | ||||||
| EOF | EOF | ||||||
| @@ -82,7 +83,7 @@ while test $# -gt 0; do | |||||||
| 	if test "@USE_SSLEAY@" = "1"; then | 	if test "@USE_SSLEAY@" = "1"; then | ||||||
|           echo "SSL" |           echo "SSL" | ||||||
|           NTLM=1 # OpenSSL implies NTLM |           NTLM=1 # OpenSSL implies NTLM | ||||||
|         elif test -n "@USE_GNUTLS@"; then |         elif test -n "@SSL_ENABLED@"; then | ||||||
|           echo "SSL" |           echo "SSL" | ||||||
|         fi |         fi | ||||||
| 	if test "@KRB4_ENABLED@" = "1"; then | 	if test "@KRB4_ENABLED@" = "1"; then | ||||||
| @@ -112,13 +113,13 @@ while test $# -gt 0; do | |||||||
|     --protocols) |     --protocols) | ||||||
| 	if test "@CURL_DISABLE_HTTP@" != "1"; then | 	if test "@CURL_DISABLE_HTTP@" != "1"; then | ||||||
|           echo "HTTP" |           echo "HTTP" | ||||||
| 	  if test "@USE_SSLEAY@" = "1"; then | 	  if test "@SSL_ENABLED@" = "1"; then | ||||||
|             echo "HTTPS" |             echo "HTTPS" | ||||||
|           fi |           fi | ||||||
|         fi |         fi | ||||||
| 	if test "@CURL_DISABLE_FTP@" != "1"; then | 	if test "@CURL_DISABLE_FTP@" != "1"; then | ||||||
|           echo "FTP" |           echo "FTP" | ||||||
| 	  if test "@USE_SSLEAY@" = "1"; then | 	  if test "@SSL_ENABLED@" = "1"; then | ||||||
|             echo "FTPS" |             echo "FTPS" | ||||||
|           fi |           fi | ||||||
|         fi |         fi | ||||||
| @@ -131,12 +132,19 @@ while test $# -gt 0; do | |||||||
| 	if test "@CURL_DISABLE_LDAP@" != "1"; then | 	if test "@CURL_DISABLE_LDAP@" != "1"; then | ||||||
|           echo "LDAP" |           echo "LDAP" | ||||||
|         fi |         fi | ||||||
|  | 	if test "@CURL_DISABLE_LDAPS@" != "1"; then | ||||||
|  |           echo "LDAPS" | ||||||
|  |         fi | ||||||
| 	if test "@CURL_DISABLE_DICT@" != "1"; then | 	if test "@CURL_DISABLE_DICT@" != "1"; then | ||||||
|           echo "DICT" |           echo "DICT" | ||||||
|         fi |         fi | ||||||
| 	if test "@CURL_DISABLE_TFTP@" != "1"; then | 	if test "@CURL_DISABLE_TFTP@" != "1"; then | ||||||
|           echo "TFTP" |           echo "TFTP" | ||||||
|         fi |         fi | ||||||
|  | 	if test "@USE_LIBSSH2@" = "1"; then | ||||||
|  |           echo "SCP" | ||||||
|  |           echo "SFTP" | ||||||
|  |         fi | ||||||
| 	;; | 	;; | ||||||
|     --version) |     --version) | ||||||
| 	echo libcurl @VERSION@ | 	echo libcurl @VERSION@ | ||||||
| @@ -181,7 +189,7 @@ while test $# -gt 0; do | |||||||
|        	;; |        	;; | ||||||
|  |  | ||||||
|     --libs) |     --libs) | ||||||
| 	if test "X@libdir@" != "X/usr/lib"; then | 	if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then | ||||||
| 	   CURLLIBDIR="-L@libdir@ " | 	   CURLLIBDIR="-L@libdir@ " | ||||||
| 	else | 	else | ||||||
| 	   CURLLIBDIR="" | 	   CURLLIBDIR="" | ||||||
| @@ -193,6 +201,10 @@ while test $# -gt 0; do | |||||||
| 	fi | 	fi | ||||||
| 	;; | 	;; | ||||||
|  |  | ||||||
|  |     --static-libs) | ||||||
|  | 	echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@ @LIBS@ | ||||||
|  | 	;; | ||||||
|  |  | ||||||
|     *) |     *) | ||||||
|         echo "unknown option: $1" |         echo "unknown option: $1" | ||||||
| 	usage 1 | 	usage 1 | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ C | |||||||
| C++ | C++ | ||||||
|  |  | ||||||
|   Written by Jean-Philippe Barrette-LaPierre |   Written by Jean-Philippe Barrette-LaPierre | ||||||
|   http://rrette.com/curlpp.html |   http://rrette.com/textpattern/index.php?s=cURLpp | ||||||
|  |  | ||||||
| Ch | Ch | ||||||
|  |  | ||||||
| @@ -60,19 +60,27 @@ Euphoria | |||||||
|   http://rays-web.com/eulibcurl.htm |   http://rays-web.com/eulibcurl.htm | ||||||
|  |  | ||||||
| Ferite | Ferite | ||||||
|  |  | ||||||
|   Written by Paul Querna |   Written by Paul Querna | ||||||
|   http://www.ferite.org/ |   http://www.ferite.org/ | ||||||
|  |  | ||||||
| Gambas | Gambas | ||||||
|  |  | ||||||
|   http://gambas.sourceforge.net |   http://gambas.sourceforge.net | ||||||
|  |  | ||||||
| glib/GTK+ | glib/GTK+ | ||||||
|  |  | ||||||
|   Written by Richard Atterer |   Written by Richard Atterer | ||||||
|   http://atterer.net/glibcurl/ |   http://atterer.net/glibcurl/ | ||||||
|  |  | ||||||
|  | Haskell | ||||||
|  |  | ||||||
|  |   Written by Galois, Inc | ||||||
|  |   http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl | ||||||
|  |  | ||||||
| Java | Java | ||||||
|  |  | ||||||
|   Maintained by Vic Hanson |   Maintained by [blank] | ||||||
|   http://curl.haxx.se/libcurl/java/ |   http://curl.haxx.se/libcurl/java/ | ||||||
|  |  | ||||||
| Lisp | Lisp | ||||||
| @@ -82,9 +90,12 @@ Lisp | |||||||
|  |  | ||||||
| Lua | Lua | ||||||
|  |  | ||||||
|   LuaCURL Written by Alexander Marinov |   luacurl by Alexander Marinov | ||||||
|   http://luacurl.luaforge.net/ |   http://luacurl.luaforge.net/ | ||||||
|  |  | ||||||
|  |   Lua-cURL by J<>rgen H<>tzel | ||||||
|  |   http://luaforge.net/projects/lua-curl/ | ||||||
|  |  | ||||||
| Mono | Mono | ||||||
|  |  | ||||||
|   Written by Jeffrey Phillips |   Written by Jeffrey Phillips | ||||||
| @@ -92,7 +103,7 @@ Mono | |||||||
|  |  | ||||||
| .NET | .NET | ||||||
|  |  | ||||||
|   libcurl-net Written by Jeffrey Phillips |   libcurl-net by Jeffrey Phillips | ||||||
|   http://sourceforge.net/projects/libcurl-net/ |   http://sourceforge.net/projects/libcurl-net/ | ||||||
|  |  | ||||||
| Object-Pascal | Object-Pascal | ||||||
| @@ -127,12 +138,12 @@ PostgreSQL | |||||||
|  |  | ||||||
| Python | Python | ||||||
|  |  | ||||||
|   PycURL is written by Kjetil Jacobsen |   PycURL by Kjetil Jacobsen | ||||||
|   http://pycurl.sourceforge.net/ |   http://pycurl.sourceforge.net/ | ||||||
|  |  | ||||||
| R | R | ||||||
|  |  | ||||||
|   RCurl is written by Duncan Temple Lang |   RCurl by Duncan Temple Lang | ||||||
|   http://www.omegahat.org/RCurl/ |   http://www.omegahat.org/RCurl/ | ||||||
|  |  | ||||||
| Rexx | Rexx | ||||||
| @@ -140,39 +151,52 @@ Rexx | |||||||
|   Written Mark Hessling |   Written Mark Hessling | ||||||
|   http://rexxcurl.sourceforge.net/ |   http://rexxcurl.sourceforge.net/ | ||||||
|  |  | ||||||
|  | RPG | ||||||
|  |  | ||||||
|  |   Support for ILE/RPG on OS/400 is included in source distribution | ||||||
|  |   http://curl.haxx.se/libcurl/ | ||||||
|  |   See packages/OS400/README.OS400 and packages/OS400/curl.inc.in | ||||||
|  |  | ||||||
| Ruby | Ruby | ||||||
|  |  | ||||||
|   Written by Ross Bamford |   curb - written by Ross Bamford | ||||||
|   http://curb.rubyforge.org/ |   http://curb.rubyforge.org/ | ||||||
|  |  | ||||||
|  |   ruby-curl-multi - written by Kristjan Petursson and Keith Rarick | ||||||
|  |   http://curl-multi.rubyforge.org/ | ||||||
|  |  | ||||||
| Scheme | Scheme | ||||||
|  |  | ||||||
|   Bigloo binding written by Kirill Lisovsky |   Bigloo binding by Kirill Lisovsky | ||||||
|   http://curl.haxx.se/libcurl/scheme/ |   http://curl.haxx.se/libcurl/scheme/ | ||||||
|  |  | ||||||
| S-Lang | S-Lang | ||||||
|  |  | ||||||
|   S-Lang binding written by John E Davis |   S-Lang binding by John E Davis | ||||||
|   http://www.jedsoft.org/slang/modules/curl.html |   http://www.jedsoft.org/slang/modules/curl.html | ||||||
|  |  | ||||||
| Smalltalk | Smalltalk | ||||||
|  |  | ||||||
|   Smalltalk binding written by Danil Osipchuk |   Smalltalk binding by Danil Osipchuk | ||||||
|   http://www.squeaksource.com/CurlPlugin/ |   http://www.squeaksource.com/CurlPlugin/ | ||||||
|  |  | ||||||
|  | SP-Forth | ||||||
|  |   SP-Forth binding by ygrek | ||||||
|  |   http://www.forth.org.ru/~ac/lib/lin/curl/ | ||||||
|  |  | ||||||
| SPL | SPL | ||||||
|  |  | ||||||
|   SPL binding written by Clifford Wolf |   SPL binding by Clifford Wolf | ||||||
|   http://www.clifford.at/spl/ |   http://www.clifford.at/spl/ | ||||||
|  |  | ||||||
| Tcl | Tcl | ||||||
|  |  | ||||||
|   Tclcurl is written by Andr<64>s Garc<72>a |   Tclcurl by Andr<64>s Garc<72>a | ||||||
|   http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html |   http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html | ||||||
|  |  | ||||||
| Visual Basic | Visual Basic | ||||||
|  |  | ||||||
|   libcurl-vb is written by Jeffrey Phillips |   libcurl-vb by Jeffrey Phillips | ||||||
|   http://sourceforge.net/projects/libcurl-vb/ |   http://sourceforge.net/projects/libcurl-vb/ | ||||||
|  |  | ||||||
| Q | Q | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ $Id$ | |||||||
| BUGS | BUGS | ||||||
|  |  | ||||||
|   Curl and libcurl have grown substantially since the beginning. At the time |   Curl and libcurl have grown substantially since the beginning. At the time | ||||||
|   of writing (August 2003), there are about 40000 lines of source code, and by |   of writing (July 2007), there are about 47000 lines of source code, and by | ||||||
|   the time you read this it has probably grown even more. |   the time you read this it has probably grown even more. | ||||||
|  |  | ||||||
|   Of course there are lots of bugs left. And lots of misfeatures. |   Of course there are lots of bugs left. And lots of misfeatures. | ||||||
| @@ -39,6 +39,7 @@ WHAT TO REPORT | |||||||
|    - your operating system's name and version number (uname -a under a unix |    - your operating system's name and version number (uname -a under a unix | ||||||
|      is fine) |      is fine) | ||||||
|    - what version of curl you're using (curl -V is fine) |    - what version of curl you're using (curl -V is fine) | ||||||
|  |    - versions of the used libraries that libcurl is built to use | ||||||
|    - what URL you were working with (if possible), at least which protocol |    - what URL you were working with (if possible), at least which protocol | ||||||
|  |  | ||||||
|   and anything and everything else you think matters. Tell us what you |   and anything and everything else you think matters. Tell us what you | ||||||
|   | |||||||
| @@ -10,16 +10,46 @@ | |||||||
|  mind when you decide to contribute to the project. This concerns new features |  mind when you decide to contribute to the project. This concerns new features | ||||||
|  as well as corrections to existing flaws or bugs. |  as well as corrections to existing flaws or bugs. | ||||||
|  |  | ||||||
| Join the Community |  1. Learning cURL | ||||||
|  |  1.1 Join the Community | ||||||
|  |  1.2 License | ||||||
|  |  1.3 What To Read | ||||||
|  |  | ||||||
|  |  2. cURL Coding Standards | ||||||
|  |  2.1 Naming | ||||||
|  |  2.2 Indenting | ||||||
|  |  2.3 Commenting | ||||||
|  |  2.4 Line Lengths | ||||||
|  |  2.5 General Style | ||||||
|  |  2.6 Non-clobbering All Over | ||||||
|  |  2.7 Platform Dependent Code | ||||||
|  |  2.8 Write Separate Patches | ||||||
|  |  2.9 Patch Against Recent Sources | ||||||
|  |  2.10 Document | ||||||
|  |  2.11 Test Cases | ||||||
|  |  | ||||||
|  |  3. Pushing Out Your Changes  | ||||||
|  |  3.1 Write Access to CVS Repository | ||||||
|  |  3.2 How To Make a Patch | ||||||
|  |  3.3 How to get your changes into the main sources | ||||||
|  |  | ||||||
|  | ============================================================================== | ||||||
|  |  | ||||||
|  | 1. Learning cURL | ||||||
|  |  | ||||||
|  | 1.1 Join the Community | ||||||
|  |  | ||||||
|  Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing |  Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing | ||||||
|  list(s).  Read up on details before you post questions. Read this file before |  list(s).  Read up on details before you post questions. Read this file before | ||||||
|  you start sending patches! We prefer patches and discussions being held on |  you start sending patches! We prefer patches and discussions being held on | ||||||
|  the mailing list(s), not sent to individuals. |  the mailing list(s), not sent to individuals. | ||||||
|  |  | ||||||
|  |  Before posting to one of the curl mailing lists, please read up on the mailing | ||||||
|  |  list etiquette: http://curl.haxx.se/mail/etiquette.html | ||||||
|  |  | ||||||
|  We also hang out on IRC in #curl on irc.freenode.net |  We also hang out on IRC in #curl on irc.freenode.net | ||||||
|  |  | ||||||
| License | 1.2. License | ||||||
|  |  | ||||||
|  When contributing with code, you agree to put your changes and new code under |  When contributing with code, you agree to put your changes and new code under | ||||||
|  the same license curl and libcurl is already using unless stated and agreed |  the same license curl and libcurl is already using unless stated and agreed | ||||||
| @@ -43,14 +73,16 @@ License | |||||||
|  give credit but also to keep a trace back to who made what changes. Please |  give credit but also to keep a trace back to who made what changes. Please | ||||||
|  always provide us with your full real name when contributing! |  always provide us with your full real name when contributing! | ||||||
|  |  | ||||||
| What To Read | 1.3 What To Read | ||||||
|  |  | ||||||
|  Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the |  Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the | ||||||
|  most recent CHANGES. Just lurking on the libcurl mailing list is gonna give |  most recent CHANGES. Just lurking on the libcurl mailing list is gonna give | ||||||
|  you a lot of insights on what's going on right now. Asking there is a good |  you a lot of insights on what's going on right now. Asking there is a good | ||||||
|  idea too. |  idea too. | ||||||
|  |  | ||||||
| Naming | 2. cURL Coding Standards | ||||||
|  |  | ||||||
|  | 2.1 Naming | ||||||
|  |  | ||||||
|  Try using a non-confusing naming scheme for your new functions and variable |  Try using a non-confusing naming scheme for your new functions and variable | ||||||
|  names. It doesn't necessarily have to mean that you should use the same as in |  names. It doesn't necessarily have to mean that you should use the same as in | ||||||
| @@ -61,7 +93,7 @@ Naming | |||||||
|  See the INTERNALS document on how we name non-exported library-global |  See the INTERNALS document on how we name non-exported library-global | ||||||
|  symbols. |  symbols. | ||||||
|  |  | ||||||
| Indenting | 2.2 Indenting | ||||||
|  |  | ||||||
|  Please try using the same indenting levels and bracing method as all the |  Please try using the same indenting levels and bracing method as all the | ||||||
|  other code already does. It makes the source code a lot easier to follow if |  other code already does. It makes the source code a lot easier to follow if | ||||||
| @@ -70,7 +102,9 @@ Indenting | |||||||
|  using spaces only (no tabs) and having the opening brace ({) on the same line |  using spaces only (no tabs) and having the opening brace ({) on the same line | ||||||
|  as the if() or while(). |  as the if() or while(). | ||||||
|  |  | ||||||
| Commenting |  Also note that we use if() and while() with no space before the parenthesis. | ||||||
|  |  | ||||||
|  | 2.3 Commenting | ||||||
|  |  | ||||||
|  Comment your source code extensively using C comments (/* comment */), DO NOT |  Comment your source code extensively using C comments (/* comment */), DO NOT | ||||||
|  use C++ comments (// this style). Commented code is quality code and enables |  use C++ comments (// this style). Commented code is quality code and enables | ||||||
| @@ -78,12 +112,16 @@ Commenting | |||||||
|  replaced when someone wants to extend things, since other persons' source |  replaced when someone wants to extend things, since other persons' source | ||||||
|  code can get quite hard to read. |  code can get quite hard to read. | ||||||
|  |  | ||||||
| General Style | 2.4 Line Lengths | ||||||
|  |  | ||||||
|  |  We try to keep source lines shorter than 80 columns. | ||||||
|  |  | ||||||
|  | 2.5 General Style | ||||||
|  |  | ||||||
|  Keep your functions small. If they're small you avoid a lot of mistakes and |  Keep your functions small. If they're small you avoid a lot of mistakes and | ||||||
|  you don't accidentally mix up variables etc. |  you don't accidentally mix up variables etc. | ||||||
|  |  | ||||||
| Non-clobbering All Over | 2.6 Non-clobbering All Over | ||||||
|  |  | ||||||
|  When you write new functionality or fix bugs, it is important that you don't |  When you write new functionality or fix bugs, it is important that you don't | ||||||
|  fiddle all over the source files and functions. Remember that it is likely |  fiddle all over the source files and functions. Remember that it is likely | ||||||
| @@ -92,14 +130,14 @@ Non-clobbering All Over | |||||||
|  functionality, try writing it in a new source file. If you fix bugs, try to |  functionality, try writing it in a new source file. If you fix bugs, try to | ||||||
|  fix one bug at a time and send them as separate patches. |  fix one bug at a time and send them as separate patches. | ||||||
|  |  | ||||||
| Platform Dependent Code | 2.7 Platform Dependent Code | ||||||
|  |  | ||||||
|  Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for |  Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for | ||||||
|  particular operating systems or hardware in the #ifdef lines. The |  particular operating systems or hardware in the #ifdef lines. The | ||||||
|  HAVE_FEATURE shall be generated by the configure script for unix-like systems |  HAVE_FEATURE shall be generated by the configure script for unix-like systems | ||||||
|  and they are hard-coded in the config-[system].h files for the others. |  and they are hard-coded in the config-[system].h files for the others. | ||||||
|  |  | ||||||
| Separate Patches | 2.8 Write Separate Patches | ||||||
|  |  | ||||||
|  It is annoying when you get a huge patch from someone that is said to fix 511 |  It is annoying when you get a huge patch from someone that is said to fix 511 | ||||||
|  odd problems, but discussions and opinions don't agree with 510 of them - or |  odd problems, but discussions and opinions don't agree with 510 of them - or | ||||||
| @@ -110,14 +148,14 @@ Separate Patches | |||||||
|  description exactly what they correct so that all patches can be selectively |  description exactly what they correct so that all patches can be selectively | ||||||
|  applied by the maintainer or other interested parties. |  applied by the maintainer or other interested parties. | ||||||
|  |  | ||||||
| Patch Against Recent Sources | 2.9 Patch Against Recent Sources | ||||||
|  |  | ||||||
|  Please try to get the latest available sources to make your patches |  Please try to get the latest available sources to make your patches | ||||||
|  against. It makes the life of the developers so much easier. The very best is |  against. It makes the life of the developers so much easier. The very best is | ||||||
|  if you get the most up-to-date sources from the CVS repository, but the |  if you get the most up-to-date sources from the CVS repository, but the | ||||||
|  latest release archive is quite OK as well! |  latest release archive is quite OK as well! | ||||||
|  |  | ||||||
| Document | 2.10 Document | ||||||
|  |  | ||||||
|  Writing docs is dead boring and one of the big problems with many open source |  Writing docs is dead boring and one of the big problems with many open source | ||||||
|  projects. Someone's gotta do it. It makes it a lot easier if you submit a |  projects. Someone's gotta do it. It makes it a lot easier if you submit a | ||||||
| @@ -128,16 +166,7 @@ Document | |||||||
|  ASCII files. All HTML files on the web site and in the release archives are |  ASCII files. All HTML files on the web site and in the release archives are | ||||||
|  generated from the nroff/ASCII versions. |  generated from the nroff/ASCII versions. | ||||||
|  |  | ||||||
| Write Access to CVS Repository | 2.11 Test Cases | ||||||
|  |  | ||||||
|  If you are a frequent contributor, or have another good reason, you can of |  | ||||||
|  course get write access to the CVS repository and then you'll be able to |  | ||||||
|  check-in all your changes straight into the CVS tree instead of sending all |  | ||||||
|  changes by mail as patches. Just ask if this is what you'd want. You will be |  | ||||||
|  required to have posted a few quality patches first, before you can be |  | ||||||
|  granted write access. |  | ||||||
|  |  | ||||||
| Test Cases |  | ||||||
|  |  | ||||||
|  Since the introduction of the test suite, we can quickly verify that the main |  Since the introduction of the test suite, we can quickly verify that the main | ||||||
|  features are working as they're supposed to. To maintain this situation and |  features are working as they're supposed to. To maintain this situation and | ||||||
| @@ -146,7 +175,18 @@ Test Cases | |||||||
|  test case that verifies that it works as documented. If every submitter also |  test case that verifies that it works as documented. If every submitter also | ||||||
|  posts a few test cases, it won't end up as a heavy burden on a single person! |  posts a few test cases, it won't end up as a heavy burden on a single person! | ||||||
|  |  | ||||||
| How To Make a Patch | 3. Pushing Out Your Changes  | ||||||
|  |  | ||||||
|  | 3.1 Write Access to CVS Repository | ||||||
|  |  | ||||||
|  |  If you are a frequent contributor, or have another good reason, you can of | ||||||
|  |  course get write access to the CVS repository and then you'll be able to | ||||||
|  |  check-in all your changes straight into the CVS tree instead of sending all | ||||||
|  |  changes by mail as patches. Just ask if this is what you'd want. You will be | ||||||
|  |  required to have posted a few quality patches first, before you can be | ||||||
|  |  granted write access. | ||||||
|  |  | ||||||
|  | 3.2 How To Make a Patch | ||||||
|  |  | ||||||
|  Keep a copy of the unmodified curl sources. Make your changes in a separate |  Keep a copy of the unmodified curl sources. Make your changes in a separate | ||||||
|  source tree. When you think you have something that you want to offer the |  source tree. When you think you have something that you want to offer the | ||||||
| @@ -166,7 +206,7 @@ How To Make a Patch | |||||||
|  |  | ||||||
|  For unix-like operating systems: |  For unix-like operating systems: | ||||||
|  |  | ||||||
|         http://www.fsf.org/software/patch/patch.html |    http://www.gnu.org/software/patch/patch.html | ||||||
|    http://www.gnu.org/directory/diffutils.html |    http://www.gnu.org/directory/diffutils.html | ||||||
|  |  | ||||||
|  For Windows: |  For Windows: | ||||||
| @@ -174,7 +214,7 @@ How To Make a Patch | |||||||
|    http://gnuwin32.sourceforge.net/packages/patch.htm |    http://gnuwin32.sourceforge.net/packages/patch.htm | ||||||
|    http://gnuwin32.sourceforge.net/packages/diffutils.htm |    http://gnuwin32.sourceforge.net/packages/diffutils.htm | ||||||
|  |  | ||||||
| How to get your patches into the libcurl sources | 3.3 How to get your changes into the main sources | ||||||
|  |  | ||||||
|  1. Submit your patch to the curl-library mailing list |  1. Submit your patch to the curl-library mailing list | ||||||
|  |  | ||||||
| @@ -189,5 +229,5 @@ How to get your patches into the libcurl sources | |||||||
|     simply drop such patches from my TODO list. |     simply drop such patches from my TODO list. | ||||||
|  |  | ||||||
|  5. If you've followed the above mentioned paragraphs and your patch still |  5. If you've followed the above mentioned paragraphs and your patch still | ||||||
|     hasn't been incorporated after some weeks, consider resubmitting them to |     hasn't been incorporated after some weeks, consider resubmitting it to the | ||||||
|     the list. |     list. | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user